aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-15 06:18:15 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-15 06:18:15 -0400
commitdca2d6ac09d9ef59ff46820d4f0c94b08a671202 (patch)
treefdec753b842dad09e3a4151954fab3eb5c43500d /arch
parentd6a65dffb30d8636b1e5d4c201564ef401a246cf (diff)
parent18240904960a39e582ced8ba8ececb10b8c22dd3 (diff)
Merge branch 'linus' into tracing/hw-breakpoints
Conflicts: arch/x86/kernel/process_64.c Semantic conflict fixed in: arch/x86/kvm/x86.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig12
-rw-r--r--arch/alpha/include/asm/socket.h2
-rw-r--r--arch/alpha/include/asm/thread_info.h5
-rw-r--r--arch/alpha/kernel/signal.c8
-rw-r--r--arch/arm/Kconfig264
-rw-r--r--arch/arm/Kconfig.debug1
-rw-r--r--arch/arm/Makefile17
-rw-r--r--arch/arm/boot/Makefile9
-rw-r--r--arch/arm/boot/compressed/head.S184
-rw-r--r--arch/arm/common/vic.c95
-rw-r--r--arch/arm/configs/bcmring_defconfig725
-rw-r--r--arch/arm/configs/cpu9260_defconfig1338
-rw-r--r--arch/arm/configs/cpu9g20_defconfig1328
-rw-r--r--arch/arm/configs/cpuat91_defconfig1316
-rw-r--r--arch/arm/configs/jornada720_defconfig329
-rw-r--r--arch/arm/configs/nhk8815_defconfig1316
-rw-r--r--arch/arm/configs/s5pc100_defconfig892
-rw-r--r--arch/arm/include/asm/assembler.h133
-rw-r--r--arch/arm/include/asm/device.h3
-rw-r--r--arch/arm/include/asm/elf.h3
-rw-r--r--arch/arm/include/asm/ftrace.h35
-rw-r--r--arch/arm/include/asm/futex.h1
-rw-r--r--arch/arm/include/asm/mach/mmc.h2
-rw-r--r--arch/arm/include/asm/memory.h23
-rw-r--r--arch/arm/include/asm/mmu_context.h2
-rw-r--r--arch/arm/include/asm/page-nommu.h3
-rw-r--r--arch/arm/include/asm/page.h4
-rw-r--r--arch/arm/include/asm/pgalloc.h16
-rw-r--r--arch/arm/include/asm/pgtable.h37
-rw-r--r--arch/arm/include/asm/ptrace.h8
-rw-r--r--arch/arm/include/asm/socket.h3
-rw-r--r--arch/arm/include/asm/thread_info.h5
-rw-r--r--arch/arm/include/asm/uaccess.h7
-rw-r--r--arch/arm/include/asm/unified.h126
-rw-r--r--arch/arm/include/asm/unistd.h7
-rw-r--r--arch/arm/kernel/Makefile4
-rw-r--r--arch/arm/kernel/armksyms.c1
-rw-r--r--arch/arm/kernel/calls.S10
-rw-r--r--arch/arm/kernel/crunch.c13
-rw-r--r--arch/arm/kernel/entry-armv.S179
-rw-r--r--arch/arm/kernel/entry-common.S59
-rw-r--r--arch/arm/kernel/entry-header.S92
-rw-r--r--arch/arm/kernel/head-common.S15
-rw-r--r--arch/arm/kernel/head-nommu.S16
-rw-r--r--arch/arm/kernel/head.S28
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/kernel/module.c53
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/ptrace.c8
-rw-r--r--arch/arm/kernel/return_address.c71
-rw-r--r--arch/arm/kernel/setup.c28
-rw-r--r--arch/arm/kernel/signal.c94
-rw-r--r--arch/arm/kernel/stacktrace.c4
-rw-r--r--arch/arm/kernel/unwind.c4
-rw-r--r--arch/arm/lib/ashldi3.S4
-rw-r--r--arch/arm/lib/ashrdi3.S4
-rw-r--r--arch/arm/lib/backtrace.S8
-rw-r--r--arch/arm/lib/bitops.h2
-rw-r--r--arch/arm/lib/clear_user.S15
-rw-r--r--arch/arm/lib/copy_from_user.S19
-rw-r--r--arch/arm/lib/copy_template.S24
-rw-r--r--arch/arm/lib/copy_to_user.S19
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S48
-rw-r--r--arch/arm/lib/div64.S4
-rw-r--r--arch/arm/lib/findbit.S34
-rw-r--r--arch/arm/lib/getuser.S5
-rw-r--r--arch/arm/lib/io-writesw-armv4.S5
-rw-r--r--arch/arm/lib/lshrdi3.S4
-rw-r--r--arch/arm/lib/memcpy.S7
-rw-r--r--arch/arm/lib/memmove.S28
-rw-r--r--arch/arm/lib/putuser.S15
-rw-r--r--arch/arm/lib/sha1.S2
-rw-r--r--arch/arm/lib/strncpy_from_user.S2
-rw-r--r--arch/arm/lib/strnlen_user.S2
-rw-r--r--arch/arm/mach-at91/Kconfig70
-rw-r--r--arch/arm/mach-at91/Makefile9
-rw-r--r--arch/arm/mach-at91/Makefile.boot4
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c116
-rw-r--r--arch/arm/mach-at91/at91sam9261.c22
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c14
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c360
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c1230
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c12
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c385
-rw-r--r--arch/arm/mach-at91/board-cpuat91.c185
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c14
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c4
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c1
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c389
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c79
-rw-r--r--arch/arm/mach-at91/clock.c66
-rw-r--r--arch/arm/mach-at91/generic.h2
-rw-r--r--arch/arm/mach-at91/gpio.c15
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9261.h3
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9g45.h155
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h153
-rw-r--r--arch/arm/mach-at91/include/mach/board.h14
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h23
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-at91/include/mach/timex.h10
-rw-r--r--arch/arm/mach-at91/pm.c3
-rw-r--r--arch/arm/mach-bcmring/Kconfig21
-rw-r--r--arch/arm/mach-bcmring/Makefile8
-rw-r--r--arch/arm/mach-bcmring/Makefile.boot6
-rw-r--r--arch/arm/mach-bcmring/arch.c157
-rw-r--r--arch/arm/mach-bcmring/clock.c224
-rw-r--r--arch/arm/mach-bcmring/clock.h33
-rw-r--r--arch/arm/mach-bcmring/core.c367
-rw-r--r--arch/arm/mach-bcmring/core.h30
-rw-r--r--arch/arm/mach-bcmring/csp/Makefile3
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/Makefile1
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw.c776
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c293
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c124
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c64
-rw-r--r--arch/arm/mach-bcmring/csp/dmac/Makefile1
-rw-r--r--arch/arm/mach-bcmring/csp/dmac/dmacHw.c917
-rw-r--r--arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c1017
-rw-r--r--arch/arm/mach-bcmring/csp/tmr/Makefile1
-rw-r--r--arch/arm/mach-bcmring/csp/tmr/tmrHw.c576
-rw-r--r--arch/arm/mach-bcmring/dma.c2321
-rw-r--r--arch/arm/mach-bcmring/dma_device.c593
-rw-r--r--arch/arm/mach-bcmring/include/cfg_global.h13
-rw-r--r--arch/arm/mach-bcmring/include/cfg_global_defines.h40
-rw-r--r--arch/arm/mach-bcmring/include/csp/cache.h35
-rw-r--r--arch/arm/mach-bcmring/include/csp/delay.h36
-rw-r--r--arch/arm/mach-bcmring/include/csp/dmacHw.h596
-rw-r--r--arch/arm/mach-bcmring/include/csp/errno.h32
-rw-r--r--arch/arm/mach-bcmring/include/csp/intcHw.h40
-rw-r--r--arch/arm/mach-bcmring/include/csp/module.h32
-rw-r--r--arch/arm/mach-bcmring/include/csp/reg.h114
-rw-r--r--arch/arm/mach-bcmring/include/csp/secHw.h65
-rw-r--r--arch/arm/mach-bcmring/include/csp/stdint.h30
-rw-r--r--arch/arm/mach-bcmring/include/csp/string.h34
-rw-r--r--arch/arm/mach-bcmring/include/csp/tmrHw.h263
-rw-r--r--arch/arm/mach-bcmring/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/cap.h63
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/cap_inline.h409
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h1123
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h1673
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h530
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h872
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h145
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h406
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h73
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h246
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/mm_addr.h101
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/mm_io.h147
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/secHw_def.h100
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h79
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h82
-rw-r--r--arch/arm/mach-bcmring/include/mach/dma.h826
-rw-r--r--arch/arm/mach-bcmring/include/mach/entry-macro.S86
-rw-r--r--arch/arm/mach-bcmring/include/mach/hardware.h60
-rw-r--r--arch/arm/mach-bcmring/include/mach/io.h56
-rw-r--r--arch/arm/mach-bcmring/include/mach/irqs.h132
-rw-r--r--arch/arm/mach-bcmring/include/mach/memory.h33
-rw-r--r--arch/arm/mach-bcmring/include/mach/memory_settings.h67
-rw-r--r--arch/arm/mach-bcmring/include/mach/system.h54
-rw-r--r--arch/arm/mach-bcmring/include/mach/timer.h77
-rw-r--r--arch/arm/mach-bcmring/include/mach/timex.h25
-rw-r--r--arch/arm/mach-bcmring/include/mach/uncompress.h43
-rw-r--r--arch/arm/mach-bcmring/include/mach/vmalloc.h25
-rw-r--r--arch/arm/mach-bcmring/irq.c127
-rw-r--r--arch/arm/mach-bcmring/mm.c56
-rw-r--r--arch/arm/mach-bcmring/timer.c62
-rw-r--r--arch/arm/mach-ep93xx/adssphere.c11
-rw-r--r--arch/arm/mach-ep93xx/clock.c131
-rw-r--r--arch/arm/mach-ep93xx/core.c202
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c10
-rw-r--r--arch/arm/mach-ep93xx/gesbc9312.c11
-rw-r--r--arch/arm/mach-ep93xx/gpio.c65
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h103
-rw-r--r--arch/arm/mach-ep93xx/include/mach/hardware.h17
-rw-r--r--arch/arm/mach-ep93xx/include/mach/io.h17
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h20
-rw-r--r--arch/arm/mach-ep93xx/include/mach/system.h12
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h1
-rw-r--r--arch/arm/mach-ep93xx/micro9.c11
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c15
-rw-r--r--arch/arm/mach-integrator/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c18
-rw-r--r--arch/arm/mach-ixp4xx/common.c1
-rw-r--r--arch/arm/mach-kirkwood/Kconfig6
-rw-r--r--arch/arm/mach-kirkwood/Makefile1
-rw-r--r--arch/arm/mach-kirkwood/common.c5
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h1
-rw-r--r--arch/arm/mach-kirkwood/openrd_base-setup.c84
-rw-r--r--arch/arm/mach-mx1/clock.c86
-rw-r--r--arch/arm/mach-mx1/devices.c87
-rw-r--r--arch/arm/mach-mx1/generic.c7
-rw-r--r--arch/arm/mach-mx1/mx1ads.c10
-rw-r--r--arch/arm/mach-mx1/scb9328.c16
-rw-r--r--arch/arm/mach-mx2/Kconfig35
-rw-r--r--arch/arm/mach-mx2/Makefile3
-rw-r--r--arch/arm/mach-mx2/clock_imx21.c2
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c11
-rw-r--r--arch/arm/mach-mx2/devices.c332
-rw-r--r--arch/arm/mach-mx2/devices.h9
-rw-r--r--arch/arm/mach-mx2/eukrea_cpuimx27.c234
-rw-r--r--arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c249
-rw-r--r--arch/arm/mach-mx2/generic.c12
-rw-r--r--arch/arm/mach-mx2/mx21ads.c44
-rw-r--r--arch/arm/mach-mx2/mx27ads.c38
-rw-r--r--arch/arm/mach-mx2/mx27lite.c2
-rw-r--r--arch/arm/mach-mx2/mx27pdk.c2
-rw-r--r--arch/arm/mach-mx2/pca100.c244
-rw-r--r--arch/arm/mach-mx2/pcm038.c17
-rw-r--r--arch/arm/mach-mx2/pcm970-baseboard.c112
-rw-r--r--arch/arm/mach-mx25/Kconfig9
-rw-r--r--arch/arm/mach-mx25/Makefile3
-rw-r--r--arch/arm/mach-mx25/Makefile.boot3
-rw-r--r--arch/arm/mach-mx25/clock.c219
-rw-r--r--arch/arm/mach-mx25/devices.c402
-rw-r--r--arch/arm/mach-mx25/devices.h19
-rw-r--r--arch/arm/mach-mx25/mm.c76
-rw-r--r--arch/arm/mach-mx25/mx25pdk.c58
-rw-r--r--arch/arm/mach-mx3/armadillo5x0.c2
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c22
-rw-r--r--arch/arm/mach-mx3/clock.c22
-rw-r--r--arch/arm/mach-mx3/devices.c163
-rw-r--r--arch/arm/mach-mx3/devices.h6
-rw-r--r--arch/arm/mach-mx3/mm.c14
-rw-r--r--arch/arm/mach-mx3/mx31ads.c2
-rw-r--r--arch/arm/mach-mx3/mx31lilly.c2
-rw-r--r--arch/arm/mach-mx3/mx31lite.c7
-rw-r--r--arch/arm/mach-mx3/mx31moboard-devboard.c43
-rw-r--r--arch/arm/mach-mx3/mx31moboard-marxbot.c55
-rw-r--r--arch/arm/mach-mx3/mx31moboard.c134
-rw-r--r--arch/arm/mach-mx3/mx31pdk.c2
-rw-r--r--arch/arm/mach-mx3/mx35pdk.c2
-rw-r--r--arch/arm/mach-mx3/pcm037.c42
-rw-r--r--arch/arm/mach-mx3/pcm043.c8
-rw-r--r--arch/arm/mach-mx3/qong.c7
-rw-r--r--arch/arm/mach-mxc91231/Kconfig11
-rw-r--r--arch/arm/mach-mxc91231/Makefile2
-rw-r--r--arch/arm/mach-mxc91231/Makefile.boot3
-rw-r--r--arch/arm/mach-mxc91231/clock.c642
-rw-r--r--arch/arm/mach-mxc91231/crm_regs.h399
-rw-r--r--arch/arm/mach-mxc91231/devices.c251
-rw-r--r--arch/arm/mach-mxc91231/devices.h13
-rw-r--r--arch/arm/mach-mxc91231/iomux.c177
-rw-r--r--arch/arm/mach-mxc91231/magx-zn5.c63
-rw-r--r--arch/arm/mach-mxc91231/mm.c94
-rw-r--r--arch/arm/mach-mxc91231/system.c51
-rw-r--r--arch/arm/mach-netx/include/mach/entry-macro.S4
-rw-r--r--arch/arm/mach-nomadik/Kconfig21
-rw-r--r--arch/arm/mach-nomadik/Makefile19
-rw-r--r--arch/arm/mach-nomadik/Makefile.boot4
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c111
-rw-r--r--arch/arm/mach-nomadik/clock.c45
-rw-r--r--arch/arm/mach-nomadik/clock.h14
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c139
-rw-r--r--arch/arm/mach-nomadik/gpio.c396
-rw-r--r--arch/arm/mach-nomadik/i2c-8815nhk.c65
-rw-r--r--arch/arm/mach-nomadik/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-nomadik/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-nomadik/include/mach/entry-macro.S43
-rw-r--r--arch/arm/mach-nomadik/include/mach/gpio.h71
-rw-r--r--arch/arm/mach-nomadik/include/mach/hardware.h90
-rw-r--r--arch/arm/mach-nomadik/include/mach/io.h22
-rw-r--r--arch/arm/mach-nomadik/include/mach/irqs.h82
-rw-r--r--arch/arm/mach-nomadik/include/mach/memory.h28
-rw-r--r--arch/arm/mach-nomadik/include/mach/mtu.h45
-rw-r--r--arch/arm/mach-nomadik/include/mach/setup.h22
-rw-r--r--arch/arm/mach-nomadik/include/mach/system.h45
-rw-r--r--arch/arm/mach-nomadik/include/mach/timex.h6
-rw-r--r--arch/arm/mach-nomadik/include/mach/uncompress.h63
-rw-r--r--arch/arm/mach-nomadik/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-nomadik/timer.c164
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c2
-rw-r--r--arch/arm/mach-omap2/mcbsp.c46
-rw-r--r--arch/arm/mach-omap2/serial.c10
-rw-r--r--arch/arm/mach-orion5x/Kconfig21
-rw-r--r--arch/arm/mach-orion5x/Makefile3
-rw-r--r--arch/arm/mach-orion5x/addr-map.c3
-rw-r--r--arch/arm/mach-orion5x/d2net-setup.c365
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c431
-rw-r--r--arch/arm/mach-pxa/include/mach/audio.h3
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x_keypad.h7
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c4
-rw-r--r--arch/arm/mach-realview/Kconfig2
-rw-r--r--arch/arm/mach-realview/core.c7
-rw-r--r--arch/arm/mach-realview/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-realview/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-realview/platsmp.c18
-rw-r--r--arch/arm/mach-realview/realview_eb.c22
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c22
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c22
-rw-r--r--arch/arm/mach-realview/realview_pba8.c22
-rw-r--r--arch/arm/mach-realview/realview_pbx.c22
-rw-r--r--arch/arm/mach-s3c2410/Kconfig18
-rw-r--r--arch/arm/mach-s3c2410/Makefile2
-rw-r--r--arch/arm/mach-s3c2410/cpu-freq.c159
-rw-r--r--arch/arm/mach-s3c2410/dma.c11
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h8
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-mem.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h23
-rw-r--r--arch/arm/mach-s3c2410/include/mach/spi.h3
-rw-r--r--arch/arm/mach-s3c2410/irq.c15
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c41
-rw-r--r--arch/arm/mach-s3c2410/pll.c95
-rw-r--r--arch/arm/mach-s3c2410/pm.c12
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c29
-rw-r--r--arch/arm/mach-s3c2412/Kconfig9
-rw-r--r--arch/arm/mach-s3c2412/Makefile1
-rw-r--r--arch/arm/mach-s3c2412/cpu-freq.c257
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c12
-rw-r--r--arch/arm/mach-s3c2440/Kconfig7
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c9
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/map.h1
-rw-r--r--arch/arm/mach-s3c6400/include/mach/map.h8
-rw-r--r--arch/arm/mach-s3c6400/s3c6400.c2
-rw-r--r--arch/arm/mach-s3c6410/Kconfig10
-rw-r--r--arch/arm/mach-s3c6410/Makefile3
-rw-r--r--arch/arm/mach-s3c6410/cpu.c2
-rw-r--r--arch/arm/mach-s3c6410/mach-hmt.c276
-rw-r--r--arch/arm/mach-s3c6410/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c6410/mach-smdk6410.c26
-rw-r--r--arch/arm/mach-s5pc100/Kconfig22
-rw-r--r--arch/arm/mach-s5pc100/Makefile17
-rw-r--r--arch/arm/mach-s5pc100/Makefile.boot2
-rw-r--r--arch/arm/mach-s5pc100/cpu.c97
-rw-r--r--arch/arm/mach-s5pc100/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-s5pc100/include/mach/entry-macro.S50
-rw-r--r--arch/arm/mach-s5pc100/include/mach/gpio-core.h21
-rw-r--r--arch/arm/mach-s5pc100/include/mach/gpio.h146
-rw-r--r--arch/arm/mach-s5pc100/include/mach/hardware.h14
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h14
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h75
-rw-r--r--arch/arm/mach-s5pc100/include/mach/memory.h18
-rw-r--r--arch/arm/mach-s5pc100/include/mach/pwm-clock.h56
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-irq.h24
-rw-r--r--arch/arm/mach-s5pc100/include/mach/system.h24
-rw-r--r--arch/arm/mach-s5pc100/include/mach/tick.h29
-rw-r--r--arch/arm/mach-s5pc100/include/mach/uncompress.h28
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c103
-rw-r--r--arch/arm/mach-u300/mmc.c2
-rw-r--r--arch/arm/mach-versatile/core.c17
-rw-r--r--arch/arm/mach-versatile/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-versatile/include/mach/irqs.h11
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c17
-rw-r--r--arch/arm/mach-w90x900/Kconfig30
-rw-r--r--arch/arm/mach-w90x900/Makefile12
-rw-r--r--arch/arm/mach-w90x900/clksel.c91
-rw-r--r--arch/arm/mach-w90x900/clock.c26
-rw-r--r--arch/arm/mach-w90x900/clock.h12
-rw-r--r--arch/arm/mach-w90x900/cpu.c212
-rw-r--r--arch/arm/mach-w90x900/cpu.h49
-rw-r--r--arch/arm/mach-w90x900/dev.c389
-rw-r--r--arch/arm/mach-w90x900/gpio.c78
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-clock.h22
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-ebi.h33
-rw-r--r--arch/arm/mach-w90x900/include/mach/w90p910_keypad.h15
-rw-r--r--arch/arm/mach-w90x900/irq.c172
-rw-r--r--arch/arm/mach-w90x900/mach-nuc910evb.c44
-rw-r--r--arch/arm/mach-w90x900/mach-nuc950evb.c44
-rw-r--r--arch/arm/mach-w90x900/mach-nuc960evb.c44
-rw-r--r--arch/arm/mach-w90x900/mach-w90p910evb.c267
-rw-r--r--arch/arm/mach-w90x900/mfp-w90p910.c116
-rw-r--r--arch/arm/mach-w90x900/mfp.c158
-rw-r--r--arch/arm/mach-w90x900/nuc910.c60
-rw-r--r--arch/arm/mach-w90x900/nuc910.h28
-rw-r--r--arch/arm/mach-w90x900/nuc950.c54
-rw-r--r--arch/arm/mach-w90x900/nuc950.h28
-rw-r--r--arch/arm/mach-w90x900/nuc960.c54
-rw-r--r--arch/arm/mach-w90x900/nuc960.h28
-rw-r--r--arch/arm/mach-w90x900/time.c153
-rw-r--r--arch/arm/mach-w90x900/w90p910.c136
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/mm/alignment.c20
-rw-r--r--arch/arm/mm/cache-v7.S16
-rw-r--r--arch/arm/mm/dma-mapping.c94
-rw-r--r--arch/arm/mm/fault.c24
-rw-r--r--arch/arm/mm/flush.c9
-rw-r--r--arch/arm/mm/highmem.c8
-rw-r--r--arch/arm/mm/init.c32
-rw-r--r--arch/arm/mm/nommu.c1
-rw-r--r--arch/arm/mm/proc-macros.S8
-rw-r--r--arch/arm/mm/proc-v7.S7
-rw-r--r--arch/arm/plat-mxc/Kconfig17
-rw-r--r--arch/arm/plat-mxc/clock.c170
-rw-r--r--arch/arm/plat-mxc/gpio.c42
-rw-r--r--arch/arm/plat-mxc/include/mach/board-armadillo5x0.h7
-rw-r--r--arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h40
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx21ads.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27ads.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27lite.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27pdk.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lilly.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lite.h3
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31moboard.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31pdk.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx35pdk.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm037.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm038.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm043.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/board-qong.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h19
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S68
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S3
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/imxfb.h29
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx25.h517
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h25
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mxc91231.h287
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v3.h35
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1.h22
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h44
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h7
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2x.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3x.h21
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h28
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc91231.h315
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h10
-rw-r--r--arch/arm/plat-mxc/include/mach/timex.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h68
-rw-r--r--arch/arm/plat-mxc/iomux-v3.c15
-rw-r--r--arch/arm/plat-mxc/irq.c6
-rw-r--r--arch/arm/plat-mxc/pwm.c19
-rw-r--r--arch/arm/plat-mxc/system.c29
-rw-r--r--arch/arm/plat-mxc/time.c39
-rw-r--r--arch/arm/plat-omap/debug-leds.c11
-rw-r--r--arch/arm/plat-omap/dma.c10
-rw-r--r--arch/arm/plat-omap/gpio.c263
-rw-r--r--arch/arm/plat-omap/include/mach/dma.h88
-rw-r--r--arch/arm/plat-omap/include/mach/mcbsp.h59
-rw-r--r--arch/arm/plat-omap/mcbsp.c403
-rw-r--r--arch/arm/plat-s3c/Kconfig5
-rw-r--r--arch/arm/plat-s3c/Makefile6
-rw-r--r--arch/arm/plat-s3c/dev-nand.c30
-rw-r--r--arch/arm/plat-s3c/include/plat/adc.h8
-rw-r--r--arch/arm/plat-s3c/include/plat/audio-simtec.h37
-rw-r--r--arch/arm/plat-s3c/include/plat/cpu-freq.h87
-rw-r--r--arch/arm/plat-s3c/include/plat/cpu.h1
-rw-r--r--arch/arm/plat-s3c/include/plat/devs.h3
-rw-r--r--arch/arm/plat-s3c/include/plat/hwmon.h41
-rw-r--r--arch/arm/plat-s3c/include/plat/map-base.h8
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h5
-rw-r--r--arch/arm/plat-s3c/pwm.c (renamed from arch/arm/plat-s3c24xx/pwm.c)5
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig66
-rw-r--r--arch/arm/plat-s3c24xx/Makefile12
-rw-r--r--arch/arm/plat-s3c24xx/adc.c64
-rw-r--r--arch/arm/plat-s3c24xx/cpu-freq-debugfs.c199
-rw-r--r--arch/arm/plat-s3c24xx/cpu-freq.c716
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c2
-rw-r--r--arch/arm/plat-s3c24xx/devs.c71
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h282
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/fiq.h13
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2410.h1
-rw-r--r--arch/arm/plat-s3c24xx/irq.c36
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c64
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-iotiming.c477
-rw-r--r--arch/arm/plat-s3c24xx/s3c2412-iotiming.c285
-rw-r--r--arch/arm/plat-s3c24xx/s3c2440-cpufreq.c311
-rw-r--r--arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c97
-rw-r--r--arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c127
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c38
-rw-r--r--arch/arm/plat-s3c64xx/Kconfig1
-rw-r--r--arch/arm/plat-s3c64xx/Makefile3
-rw-r--r--arch/arm/plat-s3c64xx/dev-audio.c (renamed from arch/arm/plat-s3c/dev-audio.c)0
-rw-r--r--arch/arm/plat-s5pc1xx/Kconfig50
-rw-r--r--arch/arm/plat-s5pc1xx/Makefile26
-rw-r--r--arch/arm/plat-s5pc1xx/cpu.c112
-rw-r--r--arch/arm/plat-s5pc1xx/dev-uart.c174
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/irqs.h182
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/pll.h38
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/regs-clock.h421
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/s5pc100.h65
-rw-r--r--arch/arm/plat-s5pc1xx/irq.c259
-rw-r--r--arch/arm/plat-s5pc1xx/s5pc100-clock.c1139
-rw-r--r--arch/arm/plat-s5pc1xx/s5pc100-init.c27
-rw-r--r--arch/arm/plat-s5pc1xx/setup-i2c0.c25
-rw-r--r--arch/arm/plat-s5pc1xx/setup-i2c1.c25
-rw-r--r--arch/arm/tools/mach-types139
-rw-r--r--arch/arm/vfp/entry.S2
-rw-r--r--arch/arm/vfp/vfphw.S48
-rw-r--r--arch/avr32/include/asm/socket.h3
-rw-r--r--arch/avr32/include/asm/thread_info.h6
-rw-r--r--arch/avr32/kernel/entry-avr32b.S2
-rw-r--r--arch/avr32/kernel/signal.c8
-rw-r--r--arch/blackfin/include/asm/bfin_rotary.h39
-rw-r--r--arch/cris/include/asm/socket.h3
-rw-r--r--arch/cris/kernel/ptrace.c8
-rw-r--r--arch/frv/include/asm/socket.h3
-rw-r--r--arch/frv/kernel/signal.c2
-rw-r--r--arch/h8300/include/asm/socket.h3
-rw-r--r--arch/h8300/include/asm/thread_info.h2
-rw-r--r--arch/h8300/kernel/signal.c8
-rw-r--r--arch/ia64/hp/sim/simeth.c2
-rw-r--r--arch/ia64/include/asm/device.h3
-rw-r--r--arch/ia64/include/asm/dma-mapping.h19
-rw-r--r--arch/ia64/include/asm/kvm_host.h4
-rw-r--r--arch/ia64/include/asm/kvm_para.h4
-rw-r--r--arch/ia64/include/asm/socket.h3
-rw-r--r--arch/ia64/kernel/head.S1
-rw-r--r--arch/ia64/kernel/head.h1
-rw-r--r--arch/ia64/kernel/process.c9
-rw-r--r--arch/ia64/kvm/Kconfig11
-rw-r--r--arch/ia64/kvm/kvm-ia64.c85
-rw-r--r--arch/ia64/kvm/vcpu.c4
-rw-r--r--arch/ia64/xen/time.c3
-rw-r--r--arch/m32r/include/asm/socket.h3
-rw-r--r--arch/m32r/include/asm/thread_info.h2
-rw-r--r--arch/m32r/kernel/signal.c8
-rw-r--r--arch/m68k/include/asm/entry_mm.h4
-rw-r--r--arch/m68k/include/asm/entry_no.h8
-rw-r--r--arch/m68k/include/asm/math-emu.h20
-rw-r--r--arch/m68k/include/asm/socket.h3
-rw-r--r--arch/m68k/include/asm/thread_info_mm.h11
-rw-r--r--arch/m68k/kernel/asm-offsets.c39
-rw-r--r--arch/m68k/kernel/entry.S22
-rw-r--r--arch/m68k/math-emu/fp_entry.S38
-rw-r--r--arch/microblaze/include/asm/device.h3
-rw-r--r--arch/mips/ar7/platform.c15
-rw-r--r--arch/mips/include/asm/socket.h2
-rw-r--r--arch/mips/include/asm/thread_info.h2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S4
-rw-r--r--arch/mips/kernel/signal.c8
-rw-r--r--arch/mn10300/include/asm/socket.h3
-rw-r--r--arch/mn10300/kernel/signal.c2
-rw-r--r--arch/parisc/include/asm/socket.h2
-rw-r--r--arch/parisc/include/asm/thread_info.h4
-rw-r--r--arch/parisc/kernel/entry.S2
-rw-r--r--arch/parisc/kernel/signal.c8
-rw-r--r--arch/powerpc/include/asm/device.h3
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h23
-rw-r--r--arch/powerpc/include/asm/kvm_host.h4
-rw-r--r--arch/powerpc/include/asm/pgtable.h6
-rw-r--r--arch/powerpc/include/asm/qe.h1
-rw-r--r--arch/powerpc/include/asm/socket.h3
-rw-r--r--arch/powerpc/include/asm/spinlock.h20
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/dma-swiotlb.c48
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S19
-rw-r--r--arch/powerpc/kernel/perf_callchain.c527
-rw-r--r--arch/powerpc/kvm/44x.c4
-rw-r--r--arch/powerpc/kvm/44x_tlb.c11
-rw-r--r--arch/powerpc/kvm/Kconfig14
-rw-r--r--arch/powerpc/kvm/Makefile4
-rw-r--r--arch/powerpc/kvm/booke.c2
-rw-r--r--arch/powerpc/kvm/e500.c7
-rw-r--r--arch/powerpc/kvm/e500_emulate.c3
-rw-r--r--arch/powerpc/kvm/e500_tlb.c26
-rw-r--r--arch/powerpc/kvm/e500_tlb.h6
-rw-r--r--arch/powerpc/kvm/emulate.c7
-rw-r--r--arch/powerpc/kvm/powerpc.c32
-rw-r--r--arch/powerpc/kvm/trace.h104
-rw-r--r--arch/powerpc/mm/slb.c37
-rw-r--r--arch/powerpc/mm/stab.c11
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c13
-rw-r--r--arch/s390/Kconfig8
-rw-r--r--arch/s390/Makefile3
-rw-r--r--arch/s390/crypto/des_s390.c11
-rw-r--r--arch/s390/crypto/sha1_s390.c26
-rw-r--r--arch/s390/crypto/sha256_s390.c26
-rw-r--r--arch/s390/crypto/sha512_s390.c36
-rw-r--r--arch/s390/hypfs/inode.c6
-rw-r--r--arch/s390/include/asm/atomic.h205
-rw-r--r--arch/s390/include/asm/checksum.h25
-rw-r--r--arch/s390/include/asm/chsc.h28
-rw-r--r--arch/s390/include/asm/cio.h223
-rw-r--r--arch/s390/include/asm/cpu.h26
-rw-r--r--arch/s390/include/asm/cpuid.h25
-rw-r--r--arch/s390/include/asm/debug.h9
-rw-r--r--arch/s390/include/asm/hardirq.h7
-rw-r--r--arch/s390/include/asm/ipl.h5
-rw-r--r--arch/s390/include/asm/kvm.h9
-rw-r--r--arch/s390/include/asm/kvm_host.h21
-rw-r--r--arch/s390/include/asm/kvm_para.h4
-rw-r--r--arch/s390/include/asm/kvm_virtio.h10
-rw-r--r--arch/s390/include/asm/lowcore.h6
-rw-r--r--arch/s390/include/asm/mmu.h1
-rw-r--r--arch/s390/include/asm/page.h4
-rw-r--r--arch/s390/include/asm/pgalloc.h1
-rw-r--r--arch/s390/include/asm/processor.h4
-rw-r--r--arch/s390/include/asm/scatterlist.h20
-rw-r--r--arch/s390/include/asm/scsw.h956
-rw-r--r--arch/s390/include/asm/setup.h2
-rw-r--r--arch/s390/include/asm/smp.h32
-rw-r--r--arch/s390/include/asm/socket.h3
-rw-r--r--arch/s390/include/asm/spinlock.h29
-rw-r--r--arch/s390/include/asm/system.h4
-rw-r--r--arch/s390/include/asm/timex.h22
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/debug.c8
-rw-r--r--arch/s390/kernel/early.c74
-rw-r--r--arch/s390/kernel/entry.S16
-rw-r--r--arch/s390/kernel/entry64.S4
-rw-r--r--arch/s390/kernel/head.S1
-rw-r--r--arch/s390/kernel/head31.S1
-rw-r--r--arch/s390/kernel/head64.S9
-rw-r--r--arch/s390/kernel/ipl.c166
-rw-r--r--arch/s390/kernel/mcount.S147
-rw-r--r--arch/s390/kernel/mcount64.S78
-rw-r--r--arch/s390/kernel/setup.c10
-rw-r--r--arch/s390/kernel/signal.c2
-rw-r--r--arch/s390/kernel/smp.c39
-rw-r--r--arch/s390/kernel/suspend.c (renamed from arch/s390/power/swsusp.c)35
-rw-r--r--arch/s390/kernel/swsusp_asm64.S (renamed from arch/s390/power/swsusp_asm64.S)2
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vmlinux.lds.S87
-rw-r--r--arch/s390/kvm/Kconfig9
-rw-r--r--arch/s390/kvm/gaccess.h23
-rw-r--r--arch/s390/kvm/intercept.c18
-rw-r--r--arch/s390/kvm/interrupt.c8
-rw-r--r--arch/s390/kvm/kvm-s390.c78
-rw-r--r--arch/s390/kvm/kvm-s390.h32
-rw-r--r--arch/s390/kvm/sigp.c60
-rw-r--r--arch/s390/mm/Makefile4
-rw-r--r--arch/s390/mm/fault.c13
-rw-r--r--arch/s390/mm/page-states.c6
-rw-r--r--arch/s390/mm/pgtable.c24
-rw-r--r--arch/s390/mm/vmem.c1
-rw-r--r--arch/s390/power/Makefile8
-rw-r--r--arch/s390/power/suspend.c40
-rw-r--r--arch/s390/power/swsusp_64.c17
-rw-r--r--arch/sh/include/asm/sh_eth.h3
-rw-r--r--arch/sh/kernel/signal_32.c2
-rw-r--r--arch/sh/kernel/signal_64.c2
-rw-r--r--arch/sparc/Kconfig15
-rw-r--r--arch/sparc/Makefile12
-rw-r--r--arch/sparc/boot/Makefile3
-rw-r--r--arch/sparc/include/asm/asi.h4
-rw-r--r--arch/sparc/include/asm/device.h3
-rw-r--r--arch/sparc/include/asm/dma-mapping.h145
-rw-r--r--arch/sparc/include/asm/irq_64.h4
-rw-r--r--arch/sparc/include/asm/leon.h362
-rw-r--r--arch/sparc/include/asm/leon_amba.h263
-rw-r--r--arch/sparc/include/asm/machines.h6
-rw-r--r--arch/sparc/include/asm/nmi.h5
-rw-r--r--arch/sparc/include/asm/pci.h3
-rw-r--r--arch/sparc/include/asm/pci_32.h105
-rw-r--r--arch/sparc/include/asm/pci_64.h88
-rw-r--r--arch/sparc/include/asm/perf_counter.h14
-rw-r--r--arch/sparc/include/asm/pgtsrmmu.h4
-rw-r--r--arch/sparc/include/asm/prom.h3
-rw-r--r--arch/sparc/include/asm/socket.h3
-rw-r--r--arch/sparc/include/asm/spinlock_32.h12
-rw-r--r--arch/sparc/include/asm/spinlock_64.h28
-rw-r--r--arch/sparc/include/asm/system_32.h1
-rw-r--r--arch/sparc/include/asm/system_64.h4
-rw-r--r--arch/sparc/include/asm/types.h27
-rw-r--r--arch/sparc/include/asm/uaccess_64.h2
-rw-r--r--arch/sparc/include/asm/unistd.h3
-rw-r--r--arch/sparc/kernel/Makefile7
-rw-r--r--arch/sparc/kernel/cpu.c5
-rw-r--r--arch/sparc/kernel/dma.c175
-rw-r--r--arch/sparc/kernel/dma.h14
-rw-r--r--arch/sparc/kernel/head_32.S5
-rw-r--r--arch/sparc/kernel/idprom.c2
-rw-r--r--arch/sparc/kernel/iommu.c20
-rw-r--r--arch/sparc/kernel/ioport.c222
-rw-r--r--arch/sparc/kernel/irq_32.c5
-rw-r--r--arch/sparc/kernel/leon_kernel.c203
-rw-r--r--arch/sparc/kernel/nmi.c72
-rw-r--r--arch/sparc/kernel/of_device_32.c40
-rw-r--r--arch/sparc/kernel/pci.c2
-rw-r--r--arch/sparc/kernel/pci_sun4v.c30
-rw-r--r--arch/sparc/kernel/pcr.c14
-rw-r--r--arch/sparc/kernel/perf_counter.c557
-rw-r--r--arch/sparc/kernel/process_64.c4
-rw-r--r--arch/sparc/kernel/prom_32.c33
-rw-r--r--arch/sparc/kernel/prom_common.c10
-rw-r--r--arch/sparc/kernel/setup_32.c5
-rw-r--r--arch/sparc/kernel/signal_32.c2
-rw-r--r--arch/sparc/kernel/signal_64.c3
-rw-r--r--arch/sparc/kernel/sys32.S2
-rw-r--r--arch/sparc/kernel/sysfs.c1
-rw-r--r--arch/sparc/kernel/systbls_32.S2
-rw-r--r--arch/sparc/kernel/systbls_64.S4
-rw-r--r--arch/sparc/mm/Makefile1
-rw-r--r--arch/sparc/mm/init_32.c4
-rw-r--r--arch/sparc/mm/leon_mm.c260
-rw-r--r--arch/sparc/mm/loadmmu.c1
-rw-r--r--arch/sparc/mm/srmmu.c53
-rw-r--r--arch/sparc/oprofile/init.c4
-rw-r--r--arch/um/drivers/net_kern.c4
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/Kconfig.cpu19
-rw-r--r--arch/x86/Makefile8
-rw-r--r--arch/x86/Makefile_32.cpu2
-rw-r--r--arch/x86/boot/video-vesa.c7
-rw-r--r--arch/x86/boot/video-vga.c10
-rw-r--r--arch/x86/boot/video.c5
-rw-r--r--arch/x86/boot/video.h20
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c19
-rw-r--r--arch/x86/ia32/ia32entry.S2
-rw-r--r--arch/x86/ia32/sys_ia32.c14
-rw-r--r--arch/x86/include/asm/alternative.h7
-rw-r--r--arch/x86/include/asm/amd_iommu.h1
-rw-r--r--arch/x86/include/asm/amd_iommu_types.h50
-rw-r--r--arch/x86/include/asm/apic.h7
-rw-r--r--arch/x86/include/asm/apicdef.h5
-rw-r--r--arch/x86/include/asm/asm.h10
-rw-r--r--arch/x86/include/asm/cpufeature.h1
-rw-r--r--arch/x86/include/asm/current.h2
-rw-r--r--arch/x86/include/asm/desc.h13
-rw-r--r--arch/x86/include/asm/desc_defs.h6
-rw-r--r--arch/x86/include/asm/device.h3
-rw-r--r--arch/x86/include/asm/dma-mapping.h18
-rw-r--r--arch/x86/include/asm/dwarf2.h18
-rw-r--r--arch/x86/include/asm/i387.h9
-rw-r--r--arch/x86/include/asm/io_apic.h13
-rw-r--r--arch/x86/include/asm/ioctls.h95
-rw-r--r--arch/x86/include/asm/ipcbuf.h29
-rw-r--r--arch/x86/include/asm/irqflags.h9
-rw-r--r--arch/x86/include/asm/kvm.h10
-rw-r--r--arch/x86/include/asm/kvm_emulate.h (renamed from arch/x86/include/asm/kvm_x86_emulate.h)0
-rw-r--r--arch/x86/include/asm/kvm_host.h60
-rw-r--r--arch/x86/include/asm/kvm_para.h2
-rw-r--r--arch/x86/include/asm/lguest.h5
-rw-r--r--arch/x86/include/asm/mman.h14
-rw-r--r--arch/x86/include/asm/module.h15
-rw-r--r--arch/x86/include/asm/msgbuf.h40
-rw-r--r--arch/x86/include/asm/msr-index.h1
-rw-r--r--arch/x86/include/asm/msr.h75
-rw-r--r--arch/x86/include/asm/nmi.h4
-rw-r--r--arch/x86/include/asm/param.h23
-rw-r--r--arch/x86/include/asm/paravirt.h746
-rw-r--r--arch/x86/include/asm/paravirt_types.h721
-rw-r--r--arch/x86/include/asm/percpu.h26
-rw-r--r--arch/x86/include/asm/perf_counter.h10
-rw-r--r--arch/x86/include/asm/pgtable.h16
-rw-r--r--arch/x86/include/asm/processor.h28
-rw-r--r--arch/x86/include/asm/scatterlist.h27
-rw-r--r--arch/x86/include/asm/shmbuf.h52
-rw-r--r--arch/x86/include/asm/socket.h61
-rw-r--r--arch/x86/include/asm/sockios.h14
-rw-r--r--arch/x86/include/asm/stackprotector.h10
-rw-r--r--arch/x86/include/asm/system.h29
-rw-r--r--arch/x86/include/asm/termbits.h199
-rw-r--r--arch/x86/include/asm/termios.h115
-rw-r--r--arch/x86/include/asm/thread_info.h2
-rw-r--r--arch/x86/include/asm/topology.h47
-rw-r--r--arch/x86/include/asm/traps.h4
-rw-r--r--arch/x86/include/asm/types.h12
-rw-r--r--arch/x86/include/asm/ucontext.h8
-rw-r--r--arch/x86/include/asm/vmx.h8
-rw-r--r--arch/x86/kernel/acpi/boot.c105
-rw-r--r--arch/x86/kernel/alternative.c58
-rw-r--r--arch/x86/kernel/amd_iommu.c489
-rw-r--r--arch/x86/kernel/amd_iommu_init.c42
-rw-r--r--arch/x86/kernel/aperture_64.c6
-rw-r--r--arch/x86/kernel/apic/apic.c110
-rw-r--r--arch/x86/kernel/apic/es7000_32.c2
-rw-r--r--arch/x86/kernel/apic/io_apic.c324
-rw-r--r--arch/x86/kernel/apic/ipi.c2
-rw-r--r--arch/x86/kernel/apic/nmi.c20
-rw-r--r--arch/x86/kernel/apic/probe_64.c6
-rw-r--r--arch/x86/kernel/apm_32.c31
-rw-r--r--arch/x86/kernel/cpu/amd.c117
-rw-r--r--arch/x86/kernel/cpu/bugs.c10
-rw-r--r--arch/x86/kernel/cpu/bugs_64.c2
-rw-r--r--arch/x86/kernel/cpu/common.c70
-rw-r--r--arch/x86/kernel/cpu/cyrix.c19
-rw-r--r--arch/x86/kernel/cpu/hypervisor.c5
-rw-r--r--arch/x86/kernel/cpu/intel.c11
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c148
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c12
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c8
-rw-r--r--arch/x86/kernel/cpu/mtrr/amd.c97
-rw-r--r--arch/x86/kernel/cpu/mtrr/centaur.c168
-rw-r--r--arch/x86/kernel/cpu/mtrr/cleanup.c390
-rw-r--r--arch/x86/kernel/cpu/mtrr/cyrix.c94
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c304
-rw-r--r--arch/x86/kernel/cpu/mtrr/if.c135
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c455
-rw-r--r--arch/x86/kernel/cpu/mtrr/mtrr.h19
-rw-r--r--arch/x86/kernel/cpu/mtrr/state.c68
-rw-r--r--arch/x86/kernel/cpu/perf_counter.c329
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c45
-rw-r--r--arch/x86/kernel/cpu/proc.c4
-rw-r--r--arch/x86/kernel/cpu/vmware.c18
-rw-r--r--arch/x86/kernel/doublefault_32.c4
-rw-r--r--arch/x86/kernel/ds.c6
-rw-r--r--arch/x86/kernel/dumpstack.c1
-rw-r--r--arch/x86/kernel/e820.c2
-rw-r--r--arch/x86/kernel/head_32.S1
-rw-r--r--arch/x86/kernel/irq_32.c5
-rw-r--r--arch/x86/kernel/kvm.c7
-rw-r--r--arch/x86/kernel/kvmclock.c4
-rw-r--r--arch/x86/kernel/mpparse.c10
-rw-r--r--arch/x86/kernel/msr.c61
-rw-r--r--arch/x86/kernel/paravirt.c3
-rw-r--r--arch/x86/kernel/pci-dma.c17
-rw-r--r--arch/x86/kernel/pci-gart_64.c5
-rw-r--r--arch/x86/kernel/pci-nommu.c29
-rw-r--r--arch/x86/kernel/pci-swiotlb.c25
-rw-r--r--arch/x86/kernel/process_32.c30
-rw-r--r--arch/x86/kernel/process_64.c36
-rw-r--r--arch/x86/kernel/signal.c2
-rw-r--r--arch/x86/kernel/smpboot.c3
-rw-r--r--arch/x86/kernel/step.c9
-rw-r--r--arch/x86/kernel/tlb_uv.c4
-rw-r--r--arch/x86/kernel/traps.c54
-rw-r--r--arch/x86/kvm/Kconfig21
-rw-r--r--arch/x86/kvm/Makefile35
-rw-r--r--arch/x86/kvm/emulate.c (renamed from arch/x86/kvm/x86_emulate.c)265
-rw-r--r--arch/x86/kvm/i8254.c160
-rw-r--r--arch/x86/kvm/i8254.h5
-rw-r--r--arch/x86/kvm/i8259.c116
-rw-r--r--arch/x86/kvm/irq.h1
-rw-r--r--arch/x86/kvm/kvm_cache_regs.h9
-rw-r--r--arch/x86/kvm/kvm_svm.h51
-rw-r--r--arch/x86/kvm/kvm_timer.h2
-rw-r--r--arch/x86/kvm/lapic.c334
-rw-r--r--arch/x86/kvm/lapic.h4
-rw-r--r--arch/x86/kvm/mmu.c587
-rw-r--r--arch/x86/kvm/mmu.h4
-rw-r--r--arch/x86/kvm/mmutrace.h220
-rw-r--r--arch/x86/kvm/paging_tmpl.h141
-rw-r--r--arch/x86/kvm/svm.c889
-rw-r--r--arch/x86/kvm/timer.c16
-rw-r--r--arch/x86/kvm/trace.h355
-rw-r--r--arch/x86/kvm/vmx.c497
-rw-r--r--arch/x86/kvm/x86.c822
-rw-r--r--arch/x86/kvm/x86.h4
-rw-r--r--arch/x86/lib/Makefile2
-rw-r--r--arch/x86/lib/msr-reg-export.c5
-rw-r--r--arch/x86/lib/msr-reg.S102
-rw-r--r--arch/x86/lib/msr.c49
-rw-r--r--arch/x86/mm/Makefile6
-rw-r--r--arch/x86/mm/fault.c51
-rw-r--r--arch/x86/mm/highmem_32.c3
-rw-r--r--arch/x86/mm/ioremap.c72
-rw-r--r--arch/x86/mm/kmemcheck/kmemcheck.c14
-rw-r--r--arch/x86/mm/pat.c2
-rw-r--r--arch/x86/mm/physaddr.c70
-rw-r--r--arch/x86/mm/physaddr.h10
-rw-r--r--arch/x86/mm/srat_32.c4
-rw-r--r--arch/x86/oprofile/nmi_int.c404
-rw-r--r--arch/x86/oprofile/op_counter.h2
-rw-r--r--arch/x86/oprofile/op_model_amd.c372
-rw-r--r--arch/x86/oprofile/op_model_p4.c72
-rw-r--r--arch/x86/oprofile/op_model_ppro.c101
-rw-r--r--arch/x86/oprofile/op_x86_model.h59
-rw-r--r--arch/x86/pci/direct.c5
-rw-r--r--arch/x86/xen/Makefile2
-rw-r--r--arch/x86/xen/enlighten.c133
-rw-r--r--arch/x86/xen/smp.c1
-rw-r--r--arch/x86/xen/spinlock.c28
-rw-r--r--arch/xtensa/include/asm/socket.h3
-rw-r--r--arch/xtensa/platforms/iss/network.c2
855 files changed, 60466 insertions, 9801 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index c72f18fde319..8847f47aa82c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -30,6 +30,18 @@ config OPROFILE_IBS
30 30
31 If unsure, say N. 31 If unsure, say N.
32 32
33config OPROFILE_EVENT_MULTIPLEX
34 bool "OProfile multiplexing support (EXPERIMENTAL)"
35 default n
36 depends on OPROFILE && X86
37 help
38 The number of hardware counters is limited. The multiplexing
39 feature enables OProfile to gather more events than counters
40 are provided by the hardware. This is realized by switching
41 between events at an user specified time interval.
42
43 If unsure, say N.
44
33config HAVE_OPROFILE 45config HAVE_OPROFILE
34 bool 46 bool
35 47
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index 3641ec1452f4..26773e3246e2 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -32,6 +32,8 @@
32#define SO_RCVTIMEO 0x1012 32#define SO_RCVTIMEO 0x1012
33#define SO_SNDTIMEO 0x1013 33#define SO_SNDTIMEO 0x1013
34#define SO_ACCEPTCONN 0x1014 34#define SO_ACCEPTCONN 0x1014
35#define SO_PROTOCOL 0x1028
36#define SO_DOMAIN 0x1029
35 37
36/* linux-specific, might as well be the same as on i386 */ 38/* linux-specific, might as well be the same as on i386 */
37#define SO_NO_CHECK 11 39#define SO_NO_CHECK 11
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 60c83abfde70..5076a8860b18 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -75,6 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
75#define TIF_UAC_SIGBUS 7 75#define TIF_UAC_SIGBUS 7
76#define TIF_MEMDIE 8 76#define TIF_MEMDIE 8
77#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ 77#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
78#define TIF_NOTIFY_RESUME 10 /* callback before returning to user */
78#define TIF_FREEZE 16 /* is freezing for suspend */ 79#define TIF_FREEZE 16 /* is freezing for suspend */
79 80
80#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 81#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -82,10 +83,12 @@ register struct thread_info *__current_thread_info __asm__("$8");
82#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 83#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
83#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 84#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
84#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 85#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
86#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
85#define _TIF_FREEZE (1<<TIF_FREEZE) 87#define _TIF_FREEZE (1<<TIF_FREEZE)
86 88
87/* Work to do on interrupt/exception return. */ 89/* Work to do on interrupt/exception return. */
88#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED) 90#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
91 _TIF_NOTIFY_RESUME)
89 92
90/* Work to do on any return to userspace. */ 93/* Work to do on any return to userspace. */
91#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ 94#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index df65eaa84c4c..0932dbb1ef8e 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -20,6 +20,7 @@
20#include <linux/binfmts.h> 20#include <linux/binfmts.h>
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/syscalls.h> 22#include <linux/syscalls.h>
23#include <linux/tracehook.h>
23 24
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/sigcontext.h> 26#include <asm/sigcontext.h>
@@ -683,4 +684,11 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
683{ 684{
684 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 685 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
685 do_signal(regs, sw, r0, r19); 686 do_signal(regs, sw, r0, r19);
687
688 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
689 clear_thread_flag(TIF_NOTIFY_RESUME);
690 tracehook_notify_resume(regs);
691 if (current->replacement_session_keyring)
692 key_replace_session_keyring();
693 }
686} 694}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aef63c8e3d2d..d778a699f577 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -46,10 +46,6 @@ config GENERIC_CLOCKEVENTS_BROADCAST
46 depends on GENERIC_CLOCKEVENTS 46 depends on GENERIC_CLOCKEVENTS
47 default y if SMP && !LOCAL_TIMERS 47 default y if SMP && !LOCAL_TIMERS
48 48
49config MMU
50 bool
51 default y
52
53config NO_IOPORT 49config NO_IOPORT
54 bool 50 bool
55 51
@@ -126,6 +122,13 @@ config ARCH_HAS_ILOG2_U32
126config ARCH_HAS_ILOG2_U64 122config ARCH_HAS_ILOG2_U64
127 bool 123 bool
128 124
125config ARCH_HAS_CPUFREQ
126 bool
127 help
128 Internal node to signify that the ARCH has CPUFREQ support
129 and that the relevant menu configurations are displayed for
130 it.
131
129config GENERIC_HWEIGHT 132config GENERIC_HWEIGHT
130 bool 133 bool
131 default y 134 default y
@@ -188,6 +191,13 @@ source "kernel/Kconfig.freezer"
188 191
189menu "System Type" 192menu "System Type"
190 193
194config MMU
195 bool "MMU-based Paged Memory Management Support"
196 default y
197 help
198 Select if you want MMU-based virtualised addressing space
199 support by paged memory management. If unsure, say 'Y'.
200
191choice 201choice
192 prompt "ARM system type" 202 prompt "ARM system type"
193 default ARCH_VERSATILE 203 default ARCH_VERSATILE
@@ -203,6 +213,7 @@ config ARCH_AAEC2000
203config ARCH_INTEGRATOR 213config ARCH_INTEGRATOR
204 bool "ARM Ltd. Integrator family" 214 bool "ARM Ltd. Integrator family"
205 select ARM_AMBA 215 select ARM_AMBA
216 select ARCH_HAS_CPUFREQ
206 select HAVE_CLK 217 select HAVE_CLK
207 select COMMON_CLKDEV 218 select COMMON_CLKDEV
208 select ICST525 219 select ICST525
@@ -217,6 +228,7 @@ config ARCH_REALVIEW
217 select ICST307 228 select ICST307
218 select GENERIC_TIME 229 select GENERIC_TIME
219 select GENERIC_CLOCKEVENTS 230 select GENERIC_CLOCKEVENTS
231 select ARCH_WANT_OPTIONAL_GPIOLIB
220 help 232 help
221 This enables support for ARM Ltd RealView boards. 233 This enables support for ARM Ltd RealView boards.
222 234
@@ -229,6 +241,7 @@ config ARCH_VERSATILE
229 select ICST307 241 select ICST307
230 select GENERIC_TIME 242 select GENERIC_TIME
231 select GENERIC_CLOCKEVENTS 243 select GENERIC_CLOCKEVENTS
244 select ARCH_WANT_OPTIONAL_GPIOLIB
232 help 245 help
233 This enables support for ARM Ltd Versatile board. 246 This enables support for ARM Ltd Versatile board.
234 247
@@ -327,6 +340,20 @@ config ARCH_H720X
327 help 340 help
328 This enables support for systems based on the Hynix HMS720x 341 This enables support for systems based on the Hynix HMS720x
329 342
343config ARCH_NOMADIK
344 bool "STMicroelectronics Nomadik"
345 select ARM_AMBA
346 select ARM_VIC
347 select CPU_ARM926T
348 select HAVE_CLK
349 select COMMON_CLKDEV
350 select GENERIC_TIME
351 select GENERIC_CLOCKEVENTS
352 select GENERIC_GPIO
353 select ARCH_REQUIRE_GPIOLIB
354 help
355 Support for the Nomadik platform by ST-Ericsson
356
330config ARCH_IOP13XX 357config ARCH_IOP13XX
331 bool "IOP13xx-based" 358 bool "IOP13xx-based"
332 depends on MMU 359 depends on MMU
@@ -493,10 +520,18 @@ config ARCH_W90X900
493 select CPU_ARM926T 520 select CPU_ARM926T
494 select ARCH_REQUIRE_GPIOLIB 521 select ARCH_REQUIRE_GPIOLIB
495 select GENERIC_GPIO 522 select GENERIC_GPIO
523 select HAVE_CLK
496 select COMMON_CLKDEV 524 select COMMON_CLKDEV
525 select GENERIC_TIME
526 select GENERIC_CLOCKEVENTS
497 help 527 help
498 Support for Nuvoton (Winbond logic dept.) ARM9 processor,You 528 Support for Nuvoton (Winbond logic dept.) ARM9 processor,
499 can login www.mcuos.com or www.nuvoton.com to know more. 529 At present, the w90x900 has been renamed nuc900, regarding
530 the ARM series product line, you can login the following
531 link address to know more.
532
533 <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
534 ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
500 535
501config ARCH_PNX4008 536config ARCH_PNX4008
502 bool "Philips Nexperia PNX4008 Mobile" 537 bool "Philips Nexperia PNX4008 Mobile"
@@ -509,6 +544,7 @@ config ARCH_PXA
509 bool "PXA2xx/PXA3xx-based" 544 bool "PXA2xx/PXA3xx-based"
510 depends on MMU 545 depends on MMU
511 select ARCH_MTD_XIP 546 select ARCH_MTD_XIP
547 select ARCH_HAS_CPUFREQ
512 select GENERIC_GPIO 548 select GENERIC_GPIO
513 select HAVE_CLK 549 select HAVE_CLK
514 select COMMON_CLKDEV 550 select COMMON_CLKDEV
@@ -551,6 +587,7 @@ config ARCH_SA1100
551 select ISA 587 select ISA
552 select ARCH_SPARSEMEM_ENABLE 588 select ARCH_SPARSEMEM_ENABLE
553 select ARCH_MTD_XIP 589 select ARCH_MTD_XIP
590 select ARCH_HAS_CPUFREQ
554 select GENERIC_GPIO 591 select GENERIC_GPIO
555 select GENERIC_TIME 592 select GENERIC_TIME
556 select GENERIC_CLOCKEVENTS 593 select GENERIC_CLOCKEVENTS
@@ -563,6 +600,7 @@ config ARCH_SA1100
563config ARCH_S3C2410 600config ARCH_S3C2410
564 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" 601 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
565 select GENERIC_GPIO 602 select GENERIC_GPIO
603 select ARCH_HAS_CPUFREQ
566 select HAVE_CLK 604 select HAVE_CLK
567 help 605 help
568 Samsung S3C2410X CPU based systems, such as the Simtec Electronics 606 Samsung S3C2410X CPU based systems, such as the Simtec Electronics
@@ -573,9 +611,18 @@ config ARCH_S3C64XX
573 bool "Samsung S3C64XX" 611 bool "Samsung S3C64XX"
574 select GENERIC_GPIO 612 select GENERIC_GPIO
575 select HAVE_CLK 613 select HAVE_CLK
614 select ARCH_HAS_CPUFREQ
576 help 615 help
577 Samsung S3C64XX series based systems 616 Samsung S3C64XX series based systems
578 617
618config ARCH_S5PC1XX
619 bool "Samsung S5PC1XX"
620 select GENERIC_GPIO
621 select HAVE_CLK
622 select CPU_V7
623 help
624 Samsung S5PC1XX series based systems
625
579config ARCH_SHARK 626config ARCH_SHARK
580 bool "Shark" 627 bool "Shark"
581 select CPU_SA110 628 select CPU_SA110
@@ -632,11 +679,24 @@ config ARCH_OMAP
632 select GENERIC_GPIO 679 select GENERIC_GPIO
633 select HAVE_CLK 680 select HAVE_CLK
634 select ARCH_REQUIRE_GPIOLIB 681 select ARCH_REQUIRE_GPIOLIB
682 select ARCH_HAS_CPUFREQ
635 select GENERIC_TIME 683 select GENERIC_TIME
636 select GENERIC_CLOCKEVENTS 684 select GENERIC_CLOCKEVENTS
637 help 685 help
638 Support for TI's OMAP platform (OMAP1 and OMAP2). 686 Support for TI's OMAP platform (OMAP1 and OMAP2).
639 687
688config ARCH_BCMRING
689 bool "Broadcom BCMRING"
690 depends on MMU
691 select CPU_V6
692 select ARM_AMBA
693 select COMMON_CLKDEV
694 select GENERIC_TIME
695 select GENERIC_CLOCKEVENTS
696 select ARCH_WANT_OPTIONAL_GPIOLIB
697 help
698 Support for Broadcom's BCMRing platform.
699
640endchoice 700endchoice
641 701
642source "arch/arm/mach-clps711x/Kconfig" 702source "arch/arm/mach-clps711x/Kconfig"
@@ -685,6 +745,7 @@ source "arch/arm/mach-kirkwood/Kconfig"
685source "arch/arm/plat-s3c24xx/Kconfig" 745source "arch/arm/plat-s3c24xx/Kconfig"
686source "arch/arm/plat-s3c64xx/Kconfig" 746source "arch/arm/plat-s3c64xx/Kconfig"
687source "arch/arm/plat-s3c/Kconfig" 747source "arch/arm/plat-s3c/Kconfig"
748source "arch/arm/plat-s5pc1xx/Kconfig"
688 749
689if ARCH_S3C2410 750if ARCH_S3C2410
690source "arch/arm/mach-s3c2400/Kconfig" 751source "arch/arm/mach-s3c2400/Kconfig"
@@ -702,6 +763,10 @@ endif
702 763
703source "arch/arm/plat-stmp3xxx/Kconfig" 764source "arch/arm/plat-stmp3xxx/Kconfig"
704 765
766if ARCH_S5PC1XX
767source "arch/arm/mach-s5pc100/Kconfig"
768endif
769
705source "arch/arm/mach-lh7a40x/Kconfig" 770source "arch/arm/mach-lh7a40x/Kconfig"
706 771
707source "arch/arm/mach-h720x/Kconfig" 772source "arch/arm/mach-h720x/Kconfig"
@@ -716,6 +781,8 @@ source "arch/arm/mach-at91/Kconfig"
716 781
717source "arch/arm/plat-mxc/Kconfig" 782source "arch/arm/plat-mxc/Kconfig"
718 783
784source "arch/arm/mach-nomadik/Kconfig"
785
719source "arch/arm/mach-netx/Kconfig" 786source "arch/arm/mach-netx/Kconfig"
720 787
721source "arch/arm/mach-ns9xxx/Kconfig" 788source "arch/arm/mach-ns9xxx/Kconfig"
@@ -730,6 +797,8 @@ source "arch/arm/mach-u300/Kconfig"
730 797
731source "arch/arm/mach-w90x900/Kconfig" 798source "arch/arm/mach-w90x900/Kconfig"
732 799
800source "arch/arm/mach-bcmring/Kconfig"
801
733# Definitions to make life easier 802# Definitions to make life easier
734config ARCH_ACORN 803config ARCH_ACORN
735 bool 804 bool
@@ -962,18 +1031,7 @@ config LOCAL_TIMERS
962 accounting to be spread across the timer interval, preventing a 1031 accounting to be spread across the timer interval, preventing a
963 "thundering herd" at every timer tick. 1032 "thundering herd" at every timer tick.
964 1033
965config PREEMPT 1034source kernel/Kconfig.preempt
966 bool "Preemptible Kernel (EXPERIMENTAL)"
967 depends on EXPERIMENTAL
968 help
969 This option reduces the latency of the kernel when reacting to
970 real-time or interactive events by allowing a low priority process to
971 be preempted even if it is in kernel mode executing a system call.
972 This allows applications to run more reliably even when the system is
973 under load.
974
975 Say Y here if you are building a kernel for a desktop, embedded
976 or real-time system. Say N if you are unsure.
977 1035
978config HZ 1036config HZ
979 int 1037 int
@@ -983,6 +1041,21 @@ config HZ
983 default AT91_TIMER_HZ if ARCH_AT91 1041 default AT91_TIMER_HZ if ARCH_AT91
984 default 100 1042 default 100
985 1043
1044config THUMB2_KERNEL
1045 bool "Compile the kernel in Thumb-2 mode"
1046 depends on CPU_V7 && EXPERIMENTAL
1047 select AEABI
1048 select ARM_ASM_UNIFIED
1049 help
1050 By enabling this option, the kernel will be compiled in
1051 Thumb-2 mode. A compiler/assembler that understand the unified
1052 ARM-Thumb syntax is needed.
1053
1054 If unsure, say N.
1055
1056config ARM_ASM_UNIFIED
1057 bool
1058
986config AEABI 1059config AEABI
987 bool "Use the ARM EABI to compile the kernel" 1060 bool "Use the ARM EABI to compile the kernel"
988 help 1061 help
@@ -1054,6 +1127,11 @@ config HIGHMEM
1054 1127
1055 If unsure, say n. 1128 If unsure, say n.
1056 1129
1130config HIGHPTE
1131 bool "Allocate 2nd-level pagetables from highmem"
1132 depends on HIGHMEM
1133 depends on !OUTER_CACHE
1134
1057source "mm/Kconfig" 1135source "mm/Kconfig"
1058 1136
1059config LEDS 1137config LEDS
@@ -1241,7 +1319,7 @@ endmenu
1241 1319
1242menu "CPU Power Management" 1320menu "CPU Power Management"
1243 1321
1244if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA || ARCH_S3C64XX) 1322if ARCH_HAS_CPUFREQ
1245 1323
1246source "drivers/cpufreq/Kconfig" 1324source "drivers/cpufreq/Kconfig"
1247 1325
@@ -1276,6 +1354,52 @@ config CPU_FREQ_S3C64XX
1276 bool "CPUfreq support for Samsung S3C64XX CPUs" 1354 bool "CPUfreq support for Samsung S3C64XX CPUs"
1277 depends on CPU_FREQ && CPU_S3C6410 1355 depends on CPU_FREQ && CPU_S3C6410
1278 1356
1357config CPU_FREQ_S3C
1358 bool
1359 help
1360 Internal configuration node for common cpufreq on Samsung SoC
1361
1362config CPU_FREQ_S3C24XX
1363 bool "CPUfreq driver for Samsung S3C24XX series CPUs"
1364 depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
1365 select CPU_FREQ_S3C
1366 help
1367 This enables the CPUfreq driver for the Samsung S3C24XX family
1368 of CPUs.
1369
1370 For details, take a look at <file:Documentation/cpu-freq>.
1371
1372 If in doubt, say N.
1373
1374config CPU_FREQ_S3C24XX_PLL
1375 bool "Support CPUfreq changing of PLL frequency"
1376 depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
1377 help
1378 Compile in support for changing the PLL frequency from the
1379 S3C24XX series CPUfreq driver. The PLL takes time to settle
1380 after a frequency change, so by default it is not enabled.
1381
1382 This also means that the PLL tables for the selected CPU(s) will
1383 be built which may increase the size of the kernel image.
1384
1385config CPU_FREQ_S3C24XX_DEBUG
1386 bool "Debug CPUfreq Samsung driver core"
1387 depends on CPU_FREQ_S3C24XX
1388 help
1389 Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
1390
1391config CPU_FREQ_S3C24XX_IODEBUG
1392 bool "Debug CPUfreq Samsung driver IO timing"
1393 depends on CPU_FREQ_S3C24XX
1394 help
1395 Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
1396
1397config CPU_FREQ_S3C24XX_DEBUGFS
1398 bool "Export debugfs for CPUFreq"
1399 depends on CPU_FREQ_S3C24XX && DEBUG_FS
1400 help
1401 Export status information via debugfs.
1402
1279endif 1403endif
1280 1404
1281source "drivers/cpuidle/Kconfig" 1405source "drivers/cpuidle/Kconfig"
@@ -1377,107 +1501,7 @@ endmenu
1377 1501
1378source "net/Kconfig" 1502source "net/Kconfig"
1379 1503
1380menu "Device Drivers" 1504source "drivers/Kconfig"
1381
1382source "drivers/base/Kconfig"
1383
1384source "drivers/connector/Kconfig"
1385
1386if ALIGNMENT_TRAP || !CPU_CP15_MMU
1387source "drivers/mtd/Kconfig"
1388endif
1389
1390source "drivers/parport/Kconfig"
1391
1392source "drivers/pnp/Kconfig"
1393
1394source "drivers/block/Kconfig"
1395
1396# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
1397
1398source "drivers/misc/Kconfig"
1399
1400source "drivers/ide/Kconfig"
1401
1402source "drivers/scsi/Kconfig"
1403
1404source "drivers/ata/Kconfig"
1405
1406source "drivers/md/Kconfig"
1407
1408source "drivers/message/fusion/Kconfig"
1409
1410source "drivers/ieee1394/Kconfig"
1411
1412source "drivers/message/i2o/Kconfig"
1413
1414source "drivers/net/Kconfig"
1415
1416source "drivers/isdn/Kconfig"
1417
1418# input before char - char/joystick depends on it. As does USB.
1419
1420source "drivers/input/Kconfig"
1421
1422source "drivers/char/Kconfig"
1423
1424source "drivers/i2c/Kconfig"
1425
1426source "drivers/spi/Kconfig"
1427
1428source "drivers/gpio/Kconfig"
1429
1430source "drivers/w1/Kconfig"
1431
1432source "drivers/power/Kconfig"
1433
1434source "drivers/hwmon/Kconfig"
1435
1436source "drivers/thermal/Kconfig"
1437
1438source "drivers/watchdog/Kconfig"
1439
1440source "drivers/ssb/Kconfig"
1441
1442#source "drivers/l3/Kconfig"
1443
1444source "drivers/mfd/Kconfig"
1445
1446source "drivers/media/Kconfig"
1447
1448source "drivers/video/Kconfig"
1449
1450source "sound/Kconfig"
1451
1452source "drivers/hid/Kconfig"
1453
1454source "drivers/usb/Kconfig"
1455
1456source "drivers/uwb/Kconfig"
1457
1458source "drivers/mmc/Kconfig"
1459
1460source "drivers/memstick/Kconfig"
1461
1462source "drivers/accessibility/Kconfig"
1463
1464source "drivers/leds/Kconfig"
1465
1466source "drivers/rtc/Kconfig"
1467
1468source "drivers/dma/Kconfig"
1469
1470source "drivers/dca/Kconfig"
1471
1472source "drivers/auxdisplay/Kconfig"
1473
1474source "drivers/regulator/Kconfig"
1475
1476source "drivers/uio/Kconfig"
1477
1478source "drivers/staging/Kconfig"
1479
1480endmenu
1481 1505
1482source "fs/Kconfig" 1506source "fs/Kconfig"
1483 1507
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index a89e4734b8f0..1a6f70e52921 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -8,6 +8,7 @@ source "lib/Kconfig.debug"
8# n, but then RMK will have to kill you ;). 8# n, but then RMK will have to kill you ;).
9config FRAME_POINTER 9config FRAME_POINTER
10 bool 10 bool
11 depends on !THUMB2_KERNEL
11 default y if !ARM_UNWIND 12 default y if !ARM_UNWIND
12 help 13 help
13 If you say N here, the resulting kernel will be slightly smaller and 14 If you say N here, the resulting kernel will be slightly smaller and
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c877d6df23d1..7350557a81e0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -93,9 +93,16 @@ ifeq ($(CONFIG_ARM_UNWIND),y)
93CFLAGS_ABI +=-funwind-tables 93CFLAGS_ABI +=-funwind-tables
94endif 94endif
95 95
96ifeq ($(CONFIG_THUMB2_KERNEL),y)
97AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=thumb,-Wa$(comma)-mauto-it)
98AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
99CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
100AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
101endif
102
96# Need -Uarm for gcc < 3.x 103# Need -Uarm for gcc < 3.x
97KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm 104KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
98KBUILD_AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float 105KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
99 106
100CHECKFLAGS += -D__arm__ 107CHECKFLAGS += -D__arm__
101 108
@@ -112,6 +119,7 @@ endif
112# by CONFIG_* macro name. 119# by CONFIG_* macro name.
113machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 120machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
114machine-$(CONFIG_ARCH_AT91) := at91 121machine-$(CONFIG_ARCH_AT91) := at91
122machine-$(CONFIG_ARCH_BCMRING) := bcmring
115machine-$(CONFIG_ARCH_CLPS711X) := clps711x 123machine-$(CONFIG_ARCH_CLPS711X) := clps711x
116machine-$(CONFIG_ARCH_DAVINCI) := davinci 124machine-$(CONFIG_ARCH_DAVINCI) := davinci
117machine-$(CONFIG_ARCH_EBSA110) := ebsa110 125machine-$(CONFIG_ARCH_EBSA110) := ebsa110
@@ -135,8 +143,10 @@ machine-$(CONFIG_ARCH_MSM) := msm
135machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 143machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
136machine-$(CONFIG_ARCH_MX1) := mx1 144machine-$(CONFIG_ARCH_MX1) := mx1
137machine-$(CONFIG_ARCH_MX2) := mx2 145machine-$(CONFIG_ARCH_MX2) := mx2
146machine-$(CONFIG_ARCH_MX25) := mx25
138machine-$(CONFIG_ARCH_MX3) := mx3 147machine-$(CONFIG_ARCH_MX3) := mx3
139machine-$(CONFIG_ARCH_NETX) := netx 148machine-$(CONFIG_ARCH_NETX) := netx
149machine-$(CONFIG_ARCH_NOMADIK) := nomadik
140machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx 150machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
141machine-$(CONFIG_ARCH_OMAP1) := omap1 151machine-$(CONFIG_ARCH_OMAP1) := omap1
142machine-$(CONFIG_ARCH_OMAP2) := omap2 152machine-$(CONFIG_ARCH_OMAP2) := omap2
@@ -150,6 +160,7 @@ machine-$(CONFIG_ARCH_RPC) := rpc
150machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 160machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
151machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 161machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
152machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 162machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
163machine-$(CONFIG_ARCH_S5PC1XX) := s5pc100
153machine-$(CONFIG_ARCH_SA1100) := sa1100 164machine-$(CONFIG_ARCH_SA1100) := sa1100
154machine-$(CONFIG_ARCH_SHARK) := shark 165machine-$(CONFIG_ARCH_SHARK) := shark
155machine-$(CONFIG_ARCH_STMP378X) := stmp378x 166machine-$(CONFIG_ARCH_STMP378X) := stmp378x
@@ -158,6 +169,7 @@ machine-$(CONFIG_ARCH_U300) := u300
158machine-$(CONFIG_ARCH_VERSATILE) := versatile 169machine-$(CONFIG_ARCH_VERSATILE) := versatile
159machine-$(CONFIG_ARCH_W90X900) := w90x900 170machine-$(CONFIG_ARCH_W90X900) := w90x900
160machine-$(CONFIG_FOOTBRIDGE) := footbridge 171machine-$(CONFIG_FOOTBRIDGE) := footbridge
172machine-$(CONFIG_ARCH_MXC91231) := mxc91231
161 173
162# Platform directory name. This list is sorted alphanumerically 174# Platform directory name. This list is sorted alphanumerically
163# by CONFIG_* macro name. 175# by CONFIG_* macro name.
@@ -168,6 +180,7 @@ plat-$(CONFIG_PLAT_ORION) := orion
168plat-$(CONFIG_PLAT_PXA) := pxa 180plat-$(CONFIG_PLAT_PXA) := pxa
169plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c 181plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
170plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c 182plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c
183plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx s3c
171plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx 184plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
172 185
173ifeq ($(CONFIG_ARCH_EBSA110),y) 186ifeq ($(CONFIG_ARCH_EBSA110),y)
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index da226abce2d0..4a590f4113e2 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -61,7 +61,7 @@ endif
61 61
62quiet_cmd_uimage = UIMAGE $@ 62quiet_cmd_uimage = UIMAGE $@
63 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ 63 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
64 -C none -a $(LOADADDR) -e $(LOADADDR) \ 64 -C none -a $(LOADADDR) -e $(STARTADDR) \
65 -n 'Linux-$(KERNELRELEASE)' -d $< $@ 65 -n 'Linux-$(KERNELRELEASE)' -d $< $@
66 66
67ifeq ($(CONFIG_ZBOOT_ROM),y) 67ifeq ($(CONFIG_ZBOOT_ROM),y)
@@ -70,6 +70,13 @@ else
70$(obj)/uImage: LOADADDR=$(ZRELADDR) 70$(obj)/uImage: LOADADDR=$(ZRELADDR)
71endif 71endif
72 72
73ifeq ($(CONFIG_THUMB2_KERNEL),y)
74# Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode
75$(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/")
76else
77$(obj)/uImage: STARTADDR=$(LOADADDR)
78endif
79
73$(obj)/uImage: $(obj)/zImage FORCE 80$(obj)/uImage: $(obj)/zImage FORCE
74 $(call if_changed,uimage) 81 $(call if_changed,uimage)
75 @echo ' Image $@ is ready' 82 @echo ' Image $@ is ready'
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 4515728c5345..fa6fbf45cf3b 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -140,7 +140,8 @@ start:
140 tst r2, #3 @ not user? 140 tst r2, #3 @ not user?
141 bne not_angel 141 bne not_angel
142 mov r0, #0x17 @ angel_SWIreason_EnterSVC 142 mov r0, #0x17 @ angel_SWIreason_EnterSVC
143 swi 0x123456 @ angel_SWI_ARM 143 ARM( swi 0x123456 ) @ angel_SWI_ARM
144 THUMB( svc 0xab ) @ angel_SWI_THUMB
144not_angel: 145not_angel:
145 mrs r2, cpsr @ turn off interrupts to 146 mrs r2, cpsr @ turn off interrupts to
146 orr r2, r2, #0xc0 @ prevent angel from running 147 orr r2, r2, #0xc0 @ prevent angel from running
@@ -161,7 +162,9 @@ not_angel:
161 162
162 .text 163 .text
163 adr r0, LC0 164 adr r0, LC0
164 ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} 165 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} )
166 THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} )
167 THUMB( ldr sp, [r0, #28] )
165 subs r0, r0, r1 @ calculate the delta offset 168 subs r0, r0, r1 @ calculate the delta offset
166 169
167 @ if delta is zero, we are 170 @ if delta is zero, we are
@@ -263,22 +266,25 @@ not_relocated: mov r0, #0
263 * r6 = processor ID 266 * r6 = processor ID
264 * r7 = architecture ID 267 * r7 = architecture ID
265 * r8 = atags pointer 268 * r8 = atags pointer
266 * r9-r14 = corrupted 269 * r9-r12,r14 = corrupted
267 */ 270 */
268 add r1, r5, r0 @ end of decompressed kernel 271 add r1, r5, r0 @ end of decompressed kernel
269 adr r2, reloc_start 272 adr r2, reloc_start
270 ldr r3, LC1 273 ldr r3, LC1
271 add r3, r2, r3 274 add r3, r2, r3
2721: ldmia r2!, {r9 - r14} @ copy relocation code 2751: ldmia r2!, {r9 - r12, r14} @ copy relocation code
273 stmia r1!, {r9 - r14} 276 stmia r1!, {r9 - r12, r14}
274 ldmia r2!, {r9 - r14} 277 ldmia r2!, {r9 - r12, r14}
275 stmia r1!, {r9 - r14} 278 stmia r1!, {r9 - r12, r14}
276 cmp r2, r3 279 cmp r2, r3
277 blo 1b 280 blo 1b
278 add sp, r1, #128 @ relocate the stack 281 mov sp, r1
282 add sp, sp, #128 @ relocate the stack
279 283
280 bl cache_clean_flush 284 bl cache_clean_flush
281 add pc, r5, r0 @ call relocation code 285 ARM( add pc, r5, r0 ) @ call relocation code
286 THUMB( add r12, r5, r0 )
287 THUMB( mov pc, r12 ) @ call relocation code
282 288
283/* 289/*
284 * We're not in danger of overwriting ourselves. Do this the simple way. 290 * We're not in danger of overwriting ourselves. Do this the simple way.
@@ -291,6 +297,7 @@ wont_overwrite: mov r0, r4
291 bl decompress_kernel 297 bl decompress_kernel
292 b call_kernel 298 b call_kernel
293 299
300 .align 2
294 .type LC0, #object 301 .type LC0, #object
295LC0: .word LC0 @ r1 302LC0: .word LC0 @ r1
296 .word __bss_start @ r2 303 .word __bss_start @ r2
@@ -431,6 +438,7 @@ ENDPROC(__setup_mmu)
431 438
432__armv4_mmu_cache_on: 439__armv4_mmu_cache_on:
433 mov r12, lr 440 mov r12, lr
441#ifdef CONFIG_MMU
434 bl __setup_mmu 442 bl __setup_mmu
435 mov r0, #0 443 mov r0, #0
436 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 444 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
@@ -444,10 +452,12 @@ __armv4_mmu_cache_on:
444 bl __common_mmu_cache_on 452 bl __common_mmu_cache_on
445 mov r0, #0 453 mov r0, #0
446 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 454 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
455#endif
447 mov pc, r12 456 mov pc, r12
448 457
449__armv7_mmu_cache_on: 458__armv7_mmu_cache_on:
450 mov r12, lr 459 mov r12, lr
460#ifdef CONFIG_MMU
451 mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0 461 mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
452 tst r11, #0xf @ VMSA 462 tst r11, #0xf @ VMSA
453 blne __setup_mmu 463 blne __setup_mmu
@@ -455,9 +465,11 @@ __armv7_mmu_cache_on:
455 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 465 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
456 tst r11, #0xf @ VMSA 466 tst r11, #0xf @ VMSA
457 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 467 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
468#endif
458 mrc p15, 0, r0, c1, c0, 0 @ read control reg 469 mrc p15, 0, r0, c1, c0, 0 @ read control reg
459 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement 470 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
460 orr r0, r0, #0x003c @ write buffer 471 orr r0, r0, #0x003c @ write buffer
472#ifdef CONFIG_MMU
461#ifdef CONFIG_CPU_ENDIAN_BE8 473#ifdef CONFIG_CPU_ENDIAN_BE8
462 orr r0, r0, #1 << 25 @ big-endian page tables 474 orr r0, r0, #1 << 25 @ big-endian page tables
463#endif 475#endif
@@ -465,6 +477,7 @@ __armv7_mmu_cache_on:
465 movne r1, #-1 477 movne r1, #-1
466 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer 478 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
467 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control 479 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
480#endif
468 mcr p15, 0, r0, c1, c0, 0 @ load control register 481 mcr p15, 0, r0, c1, c0, 0 @ load control register
469 mrc p15, 0, r0, c1, c0, 0 @ and read it back 482 mrc p15, 0, r0, c1, c0, 0 @ and read it back
470 mov r0, #0 483 mov r0, #0
@@ -498,6 +511,7 @@ __arm6_mmu_cache_on:
498 mov pc, r12 511 mov pc, r12
499 512
500__common_mmu_cache_on: 513__common_mmu_cache_on:
514#ifndef CONFIG_THUMB2_KERNEL
501#ifndef DEBUG 515#ifndef DEBUG
502 orr r0, r0, #0x000d @ Write buffer, mmu 516 orr r0, r0, #0x000d @ Write buffer, mmu
503#endif 517#endif
@@ -509,6 +523,7 @@ __common_mmu_cache_on:
5091: mcr p15, 0, r0, c1, c0, 0 @ load control register 5231: mcr p15, 0, r0, c1, c0, 0 @ load control register
510 mrc p15, 0, r0, c1, c0, 0 @ and read it back to 524 mrc p15, 0, r0, c1, c0, 0 @ and read it back to
511 sub pc, lr, r0, lsr #32 @ properly flush pipeline 525 sub pc, lr, r0, lsr #32 @ properly flush pipeline
526#endif
512 527
513/* 528/*
514 * All code following this line is relocatable. It is relocated by 529 * All code following this line is relocatable. It is relocated by
@@ -522,7 +537,7 @@ __common_mmu_cache_on:
522 * r6 = processor ID 537 * r6 = processor ID
523 * r7 = architecture ID 538 * r7 = architecture ID
524 * r8 = atags pointer 539 * r8 = atags pointer
525 * r9-r14 = corrupted 540 * r9-r12,r14 = corrupted
526 */ 541 */
527 .align 5 542 .align 5
528reloc_start: add r9, r5, r0 543reloc_start: add r9, r5, r0
@@ -531,13 +546,14 @@ reloc_start: add r9, r5, r0
531 mov r1, r4 546 mov r1, r4
5321: 5471:
533 .rept 4 548 .rept 4
534 ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernel 549 ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel
535 stmia r1!, {r0, r2, r3, r10 - r14} 550 stmia r1!, {r0, r2, r3, r10 - r12, r14}
536 .endr 551 .endr
537 552
538 cmp r5, r9 553 cmp r5, r9
539 blo 1b 554 blo 1b
540 add sp, r1, #128 @ relocate the stack 555 mov sp, r1
556 add sp, sp, #128 @ relocate the stack
541 debug_reloc_end 557 debug_reloc_end
542 558
543call_kernel: bl cache_clean_flush 559call_kernel: bl cache_clean_flush
@@ -571,7 +587,9 @@ call_cache_fn: adr r12, proc_types
571 ldr r2, [r12, #4] @ get mask 587 ldr r2, [r12, #4] @ get mask
572 eor r1, r1, r6 @ (real ^ match) 588 eor r1, r1, r6 @ (real ^ match)
573 tst r1, r2 @ & mask 589 tst r1, r2 @ & mask
574 addeq pc, r12, r3 @ call cache function 590 ARM( addeq pc, r12, r3 ) @ call cache function
591 THUMB( addeq r12, r3 )
592 THUMB( moveq pc, r12 ) @ call cache function
575 add r12, r12, #4*5 593 add r12, r12, #4*5
576 b 1b 594 b 1b
577 595
@@ -589,13 +607,15 @@ call_cache_fn: adr r12, proc_types
589 * methods. Writeback caches _must_ have the flush method 607 * methods. Writeback caches _must_ have the flush method
590 * defined. 608 * defined.
591 */ 609 */
610 .align 2
592 .type proc_types,#object 611 .type proc_types,#object
593proc_types: 612proc_types:
594 .word 0x41560600 @ ARM6/610 613 .word 0x41560600 @ ARM6/610
595 .word 0xffffffe0 614 .word 0xffffffe0
596 b __arm6_mmu_cache_off @ works, but slow 615 W(b) __arm6_mmu_cache_off @ works, but slow
597 b __arm6_mmu_cache_off 616 W(b) __arm6_mmu_cache_off
598 mov pc, lr 617 mov pc, lr
618 THUMB( nop )
599@ b __arm6_mmu_cache_on @ untested 619@ b __arm6_mmu_cache_on @ untested
600@ b __arm6_mmu_cache_off 620@ b __arm6_mmu_cache_off
601@ b __armv3_mmu_cache_flush 621@ b __armv3_mmu_cache_flush
@@ -603,76 +623,84 @@ proc_types:
603 .word 0x00000000 @ old ARM ID 623 .word 0x00000000 @ old ARM ID
604 .word 0x0000f000 624 .word 0x0000f000
605 mov pc, lr 625 mov pc, lr
626 THUMB( nop )
606 mov pc, lr 627 mov pc, lr
628 THUMB( nop )
607 mov pc, lr 629 mov pc, lr
630 THUMB( nop )
608 631
609 .word 0x41007000 @ ARM7/710 632 .word 0x41007000 @ ARM7/710
610 .word 0xfff8fe00 633 .word 0xfff8fe00
611 b __arm7_mmu_cache_off 634 W(b) __arm7_mmu_cache_off
612 b __arm7_mmu_cache_off 635 W(b) __arm7_mmu_cache_off
613 mov pc, lr 636 mov pc, lr
637 THUMB( nop )
614 638
615 .word 0x41807200 @ ARM720T (writethrough) 639 .word 0x41807200 @ ARM720T (writethrough)
616 .word 0xffffff00 640 .word 0xffffff00
617 b __armv4_mmu_cache_on 641 W(b) __armv4_mmu_cache_on
618 b __armv4_mmu_cache_off 642 W(b) __armv4_mmu_cache_off
619 mov pc, lr 643 mov pc, lr
644 THUMB( nop )
620 645
621 .word 0x41007400 @ ARM74x 646 .word 0x41007400 @ ARM74x
622 .word 0xff00ff00 647 .word 0xff00ff00
623 b __armv3_mpu_cache_on 648 W(b) __armv3_mpu_cache_on
624 b __armv3_mpu_cache_off 649 W(b) __armv3_mpu_cache_off
625 b __armv3_mpu_cache_flush 650 W(b) __armv3_mpu_cache_flush
626 651
627 .word 0x41009400 @ ARM94x 652 .word 0x41009400 @ ARM94x
628 .word 0xff00ff00 653 .word 0xff00ff00
629 b __armv4_mpu_cache_on 654 W(b) __armv4_mpu_cache_on
630 b __armv4_mpu_cache_off 655 W(b) __armv4_mpu_cache_off
631 b __armv4_mpu_cache_flush 656 W(b) __armv4_mpu_cache_flush
632 657
633 .word 0x00007000 @ ARM7 IDs 658 .word 0x00007000 @ ARM7 IDs
634 .word 0x0000f000 659 .word 0x0000f000
635 mov pc, lr 660 mov pc, lr
661 THUMB( nop )
636 mov pc, lr 662 mov pc, lr
663 THUMB( nop )
637 mov pc, lr 664 mov pc, lr
665 THUMB( nop )
638 666
639 @ Everything from here on will be the new ID system. 667 @ Everything from here on will be the new ID system.
640 668
641 .word 0x4401a100 @ sa110 / sa1100 669 .word 0x4401a100 @ sa110 / sa1100
642 .word 0xffffffe0 670 .word 0xffffffe0
643 b __armv4_mmu_cache_on 671 W(b) __armv4_mmu_cache_on
644 b __armv4_mmu_cache_off 672 W(b) __armv4_mmu_cache_off
645 b __armv4_mmu_cache_flush 673 W(b) __armv4_mmu_cache_flush
646 674
647 .word 0x6901b110 @ sa1110 675 .word 0x6901b110 @ sa1110
648 .word 0xfffffff0 676 .word 0xfffffff0
649 b __armv4_mmu_cache_on 677 W(b) __armv4_mmu_cache_on
650 b __armv4_mmu_cache_off 678 W(b) __armv4_mmu_cache_off
651 b __armv4_mmu_cache_flush 679 W(b) __armv4_mmu_cache_flush
652 680
653 .word 0x56056930 681 .word 0x56056930
654 .word 0xff0ffff0 @ PXA935 682 .word 0xff0ffff0 @ PXA935
655 b __armv4_mmu_cache_on 683 W(b) __armv4_mmu_cache_on
656 b __armv4_mmu_cache_off 684 W(b) __armv4_mmu_cache_off
657 b __armv4_mmu_cache_flush 685 W(b) __armv4_mmu_cache_flush
658 686
659 .word 0x56158000 @ PXA168 687 .word 0x56158000 @ PXA168
660 .word 0xfffff000 688 .word 0xfffff000
661 b __armv4_mmu_cache_on 689 W(b) __armv4_mmu_cache_on
662 b __armv4_mmu_cache_off 690 W(b) __armv4_mmu_cache_off
663 b __armv5tej_mmu_cache_flush 691 W(b) __armv5tej_mmu_cache_flush
664 692
665 .word 0x56056930 693 .word 0x56056930
666 .word 0xff0ffff0 @ PXA935 694 .word 0xff0ffff0 @ PXA935
667 b __armv4_mmu_cache_on 695 W(b) __armv4_mmu_cache_on
668 b __armv4_mmu_cache_off 696 W(b) __armv4_mmu_cache_off
669 b __armv4_mmu_cache_flush 697 W(b) __armv4_mmu_cache_flush
670 698
671 .word 0x56050000 @ Feroceon 699 .word 0x56050000 @ Feroceon
672 .word 0xff0f0000 700 .word 0xff0f0000
673 b __armv4_mmu_cache_on 701 W(b) __armv4_mmu_cache_on
674 b __armv4_mmu_cache_off 702 W(b) __armv4_mmu_cache_off
675 b __armv5tej_mmu_cache_flush 703 W(b) __armv5tej_mmu_cache_flush
676 704
677#ifdef CONFIG_CPU_FEROCEON_OLD_ID 705#ifdef CONFIG_CPU_FEROCEON_OLD_ID
678 /* this conflicts with the standard ARMv5TE entry */ 706 /* this conflicts with the standard ARMv5TE entry */
@@ -685,47 +713,50 @@ proc_types:
685 713
686 .word 0x66015261 @ FA526 714 .word 0x66015261 @ FA526
687 .word 0xff01fff1 715 .word 0xff01fff1
688 b __fa526_cache_on 716 W(b) __fa526_cache_on
689 b __armv4_mmu_cache_off 717 W(b) __armv4_mmu_cache_off
690 b __fa526_cache_flush 718 W(b) __fa526_cache_flush
691 719
692 @ These match on the architecture ID 720 @ These match on the architecture ID
693 721
694 .word 0x00020000 @ ARMv4T 722 .word 0x00020000 @ ARMv4T
695 .word 0x000f0000 723 .word 0x000f0000
696 b __armv4_mmu_cache_on 724 W(b) __armv4_mmu_cache_on
697 b __armv4_mmu_cache_off 725 W(b) __armv4_mmu_cache_off
698 b __armv4_mmu_cache_flush 726 W(b) __armv4_mmu_cache_flush
699 727
700 .word 0x00050000 @ ARMv5TE 728 .word 0x00050000 @ ARMv5TE
701 .word 0x000f0000 729 .word 0x000f0000
702 b __armv4_mmu_cache_on 730 W(b) __armv4_mmu_cache_on
703 b __armv4_mmu_cache_off 731 W(b) __armv4_mmu_cache_off
704 b __armv4_mmu_cache_flush 732 W(b) __armv4_mmu_cache_flush
705 733
706 .word 0x00060000 @ ARMv5TEJ 734 .word 0x00060000 @ ARMv5TEJ
707 .word 0x000f0000 735 .word 0x000f0000
708 b __armv4_mmu_cache_on 736 W(b) __armv4_mmu_cache_on
709 b __armv4_mmu_cache_off 737 W(b) __armv4_mmu_cache_off
710 b __armv5tej_mmu_cache_flush 738 W(b) __armv4_mmu_cache_flush
711 739
712 .word 0x0007b000 @ ARMv6 740 .word 0x0007b000 @ ARMv6
713 .word 0x000ff000 741 .word 0x000ff000
714 b __armv4_mmu_cache_on 742 W(b) __armv4_mmu_cache_on
715 b __armv4_mmu_cache_off 743 W(b) __armv4_mmu_cache_off
716 b __armv6_mmu_cache_flush 744 W(b) __armv6_mmu_cache_flush
717 745
718 .word 0x000f0000 @ new CPU Id 746 .word 0x000f0000 @ new CPU Id
719 .word 0x000f0000 747 .word 0x000f0000
720 b __armv7_mmu_cache_on 748 W(b) __armv7_mmu_cache_on
721 b __armv7_mmu_cache_off 749 W(b) __armv7_mmu_cache_off
722 b __armv7_mmu_cache_flush 750 W(b) __armv7_mmu_cache_flush
723 751
724 .word 0 @ unrecognised type 752 .word 0 @ unrecognised type
725 .word 0 753 .word 0
726 mov pc, lr 754 mov pc, lr
755 THUMB( nop )
727 mov pc, lr 756 mov pc, lr
757 THUMB( nop )
728 mov pc, lr 758 mov pc, lr
759 THUMB( nop )
729 760
730 .size proc_types, . - proc_types 761 .size proc_types, . - proc_types
731 762
@@ -760,22 +791,30 @@ __armv3_mpu_cache_off:
760 mov pc, lr 791 mov pc, lr
761 792
762__armv4_mmu_cache_off: 793__armv4_mmu_cache_off:
794#ifdef CONFIG_MMU
763 mrc p15, 0, r0, c1, c0 795 mrc p15, 0, r0, c1, c0
764 bic r0, r0, #0x000d 796 bic r0, r0, #0x000d
765 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off 797 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
766 mov r0, #0 798 mov r0, #0
767 mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4 799 mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
768 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 800 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
801#endif
769 mov pc, lr 802 mov pc, lr
770 803
771__armv7_mmu_cache_off: 804__armv7_mmu_cache_off:
772 mrc p15, 0, r0, c1, c0 805 mrc p15, 0, r0, c1, c0
806#ifdef CONFIG_MMU
773 bic r0, r0, #0x000d 807 bic r0, r0, #0x000d
808#else
809 bic r0, r0, #0x000c
810#endif
774 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off 811 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
775 mov r12, lr 812 mov r12, lr
776 bl __armv7_mmu_cache_flush 813 bl __armv7_mmu_cache_flush
777 mov r0, #0 814 mov r0, #0
815#ifdef CONFIG_MMU
778 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB 816 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
817#endif
779 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC 818 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC
780 mcr p15, 0, r0, c7, c10, 4 @ DSB 819 mcr p15, 0, r0, c7, c10, 4 @ DSB
781 mcr p15, 0, r0, c7, c5, 4 @ ISB 820 mcr p15, 0, r0, c7, c5, 4 @ ISB
@@ -852,7 +891,7 @@ __armv7_mmu_cache_flush:
852 b iflush 891 b iflush
853hierarchical: 892hierarchical:
854 mcr p15, 0, r10, c7, c10, 5 @ DMB 893 mcr p15, 0, r10, c7, c10, 5 @ DMB
855 stmfd sp!, {r0-r5, r7, r9, r11} 894 stmfd sp!, {r0-r7, r9-r11}
856 mrc p15, 1, r0, c0, c0, 1 @ read clidr 895 mrc p15, 1, r0, c0, c0, 1 @ read clidr
857 ands r3, r0, #0x7000000 @ extract loc from clidr 896 ands r3, r0, #0x7000000 @ extract loc from clidr
858 mov r3, r3, lsr #23 @ left align loc bit field 897 mov r3, r3, lsr #23 @ left align loc bit field
@@ -877,8 +916,12 @@ loop1:
877loop2: 916loop2:
878 mov r9, r4 @ create working copy of max way size 917 mov r9, r4 @ create working copy of max way size
879loop3: 918loop3:
880 orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 919 ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
881 orr r11, r11, r7, lsl r2 @ factor index number into r11 920 ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
921 THUMB( lsl r6, r9, r5 )
922 THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
923 THUMB( lsl r6, r7, r2 )
924 THUMB( orr r11, r11, r6 ) @ factor index number into r11
882 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way 925 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
883 subs r9, r9, #1 @ decrement the way 926 subs r9, r9, #1 @ decrement the way
884 bge loop3 927 bge loop3
@@ -889,7 +932,7 @@ skip:
889 cmp r3, r10 932 cmp r3, r10
890 bgt loop1 933 bgt loop1
891finished: 934finished:
892 ldmfd sp!, {r0-r5, r7, r9, r11} 935 ldmfd sp!, {r0-r7, r9-r11}
893 mov r10, #0 @ swith back to cache level 0 936 mov r10, #0 @ swith back to cache level 0
894 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 937 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
895iflush: 938iflush:
@@ -923,9 +966,13 @@ __armv4_mmu_cache_flush:
923 mov r11, #8 966 mov r11, #8
924 mov r11, r11, lsl r3 @ cache line size in bytes 967 mov r11, r11, lsl r3 @ cache line size in bytes
925no_cache_id: 968no_cache_id:
926 bic r1, pc, #63 @ align to longest cache line 969 mov r1, pc
970 bic r1, r1, #63 @ align to longest cache line
927 add r2, r1, r2 971 add r2, r1, r2
9281: ldr r3, [r1], r11 @ s/w flush D cache 9721:
973 ARM( ldr r3, [r1], r11 ) @ s/w flush D cache
974 THUMB( ldr r3, [r1] ) @ s/w flush D cache
975 THUMB( add r1, r1, r11 )
929 teq r1, r2 976 teq r1, r2
930 bne 1b 977 bne 1b
931 978
@@ -945,6 +992,7 @@ __armv3_mpu_cache_flush:
945 * memory, which again must be relocatable. 992 * memory, which again must be relocatable.
946 */ 993 */
947#ifdef DEBUG 994#ifdef DEBUG
995 .align 2
948 .type phexbuf,#object 996 .type phexbuf,#object
949phexbuf: .space 12 997phexbuf: .space 12
950 .size phexbuf, . - phexbuf 998 .size phexbuf, . - phexbuf
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 6ed89836e908..920ced0b73c5 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -22,10 +22,20 @@
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/sysdev.h> 24#include <linux/sysdev.h>
25#include <linux/amba/bus.h>
25 26
26#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
27#include <asm/hardware/vic.h> 28#include <asm/hardware/vic.h>
28 29
30static void vic_ack_irq(unsigned int irq)
31{
32 void __iomem *base = get_irq_chip_data(irq);
33 irq &= 31;
34 writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
35 /* moreover, clear the soft-triggered, in case it was the reason */
36 writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
37}
38
29static void vic_mask_irq(unsigned int irq) 39static void vic_mask_irq(unsigned int irq)
30{ 40{
31 void __iomem *base = get_irq_chip_data(irq); 41 void __iomem *base = get_irq_chip_data(irq);
@@ -253,12 +263,16 @@ static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg
253 263
254static struct irq_chip vic_chip = { 264static struct irq_chip vic_chip = {
255 .name = "VIC", 265 .name = "VIC",
256 .ack = vic_mask_irq, 266 .ack = vic_ack_irq,
257 .mask = vic_mask_irq, 267 .mask = vic_mask_irq,
258 .unmask = vic_unmask_irq, 268 .unmask = vic_unmask_irq,
259 .set_wake = vic_set_wake, 269 .set_wake = vic_set_wake,
260}; 270};
261 271
272/* The PL190 cell from ARM has been modified by ST, so handle both here */
273static void vik_init_st(void __iomem *base, unsigned int irq_start,
274 u32 vic_sources);
275
262/** 276/**
263 * vic_init - initialise a vectored interrupt controller 277 * vic_init - initialise a vectored interrupt controller
264 * @base: iomem base address 278 * @base: iomem base address
@@ -270,6 +284,28 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
270 u32 vic_sources, u32 resume_sources) 284 u32 vic_sources, u32 resume_sources)
271{ 285{
272 unsigned int i; 286 unsigned int i;
287 u32 cellid = 0;
288 enum amba_vendor vendor;
289
290 /* Identify which VIC cell this one is, by reading the ID */
291 for (i = 0; i < 4; i++) {
292 u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
293 cellid |= (readl(addr) & 0xff) << (8 * i);
294 }
295 vendor = (cellid >> 12) & 0xff;
296 printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n",
297 base, cellid, vendor);
298
299 switch(vendor) {
300 case AMBA_VENDOR_ST:
301 vik_init_st(base, irq_start, vic_sources);
302 return;
303 default:
304 printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
305 /* fall through */
306 case AMBA_VENDOR_ARM:
307 break;
308 }
273 309
274 /* Disable all interrupts initially. */ 310 /* Disable all interrupts initially. */
275 311
@@ -306,3 +342,60 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
306 342
307 vic_pm_register(base, irq_start, resume_sources); 343 vic_pm_register(base, irq_start, resume_sources);
308} 344}
345
346/*
347 * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
348 * The original cell has 32 interrupts, while the modified one has 64,
349 * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
350 * the probe function is called twice, with base set to offset 000
351 * and 020 within the page. We call this "second block".
352 */
353static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
354 u32 vic_sources)
355{
356 unsigned int i;
357 int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
358
359 /* Disable all interrupts initially. */
360
361 writel(0, base + VIC_INT_SELECT);
362 writel(0, base + VIC_INT_ENABLE);
363 writel(~0, base + VIC_INT_ENABLE_CLEAR);
364 writel(0, base + VIC_IRQ_STATUS);
365 writel(0, base + VIC_ITCR);
366 writel(~0, base + VIC_INT_SOFT_CLEAR);
367
368 /*
369 * Make sure we clear all existing interrupts. The vector registers
370 * in this cell are after the second block of general registers,
371 * so we can address them using standard offsets, but only from
372 * the second base address, which is 0x20 in the page
373 */
374 if (vic_2nd_block) {
375 writel(0, base + VIC_PL190_VECT_ADDR);
376 for (i = 0; i < 19; i++) {
377 unsigned int value;
378
379 value = readl(base + VIC_PL190_VECT_ADDR);
380 writel(value, base + VIC_PL190_VECT_ADDR);
381 }
382 /* ST has 16 vectors as well, but we don't enable them by now */
383 for (i = 0; i < 16; i++) {
384 void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
385 writel(0, reg);
386 }
387
388 writel(32, base + VIC_PL190_DEF_VECT_ADDR);
389 }
390
391 for (i = 0; i < 32; i++) {
392 if (vic_sources & (1 << i)) {
393 unsigned int irq = irq_start + i;
394
395 set_irq_chip(irq, &vic_chip);
396 set_irq_chip_data(irq, base);
397 set_irq_handler(irq, handle_level_irq);
398 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
399 }
400 }
401}
diff --git a/arch/arm/configs/bcmring_defconfig b/arch/arm/configs/bcmring_defconfig
new file mode 100644
index 000000000000..bcc0bac551a5
--- /dev/null
+++ b/arch/arm/configs/bcmring_defconfig
@@ -0,0 +1,725 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.31-rc3
4# Fri Jul 17 12:07:28 2009
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_TIME=y
9CONFIG_GENERIC_CLOCKEVENTS=y
10CONFIG_MMU=y
11CONFIG_GENERIC_HARDIRQS=y
12CONFIG_STACKTRACE_SUPPORT=y
13CONFIG_HAVE_LATENCYTOP_SUPPORT=y
14CONFIG_LOCKDEP_SUPPORT=y
15CONFIG_TRACE_IRQFLAGS_SUPPORT=y
16CONFIG_HARDIRQS_SW_RESEND=y
17CONFIG_GENERIC_IRQ_PROBE=y
18CONFIG_RWSEM_GENERIC_SPINLOCK=y
19CONFIG_GENERIC_HWEIGHT=y
20CONFIG_GENERIC_CALIBRATE_DELAY=y
21CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
22CONFIG_VECTORS_BASE=0xffff0000
23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
24CONFIG_CONSTRUCTORS=y
25
26#
27# General setup
28#
29CONFIG_EXPERIMENTAL=y
30CONFIG_BROKEN_ON_SMP=y
31CONFIG_LOCK_KERNEL=y
32CONFIG_INIT_ENV_ARG_LIMIT=32
33CONFIG_LOCALVERSION=""
34# CONFIG_LOCALVERSION_AUTO is not set
35# CONFIG_SWAP is not set
36CONFIG_SYSVIPC=y
37CONFIG_SYSVIPC_SYSCTL=y
38# CONFIG_POSIX_MQUEUE is not set
39# CONFIG_BSD_PROCESS_ACCT is not set
40# CONFIG_TASKSTATS is not set
41# CONFIG_AUDIT is not set
42
43#
44# RCU Subsystem
45#
46CONFIG_CLASSIC_RCU=y
47# CONFIG_TREE_RCU is not set
48# CONFIG_PREEMPT_RCU is not set
49# CONFIG_TREE_RCU_TRACE is not set
50# CONFIG_PREEMPT_RCU_TRACE is not set
51# CONFIG_IKCONFIG is not set
52CONFIG_LOG_BUF_SHIFT=17
53# CONFIG_GROUP_SCHED is not set
54# CONFIG_CGROUPS is not set
55# CONFIG_SYSFS_DEPRECATED_V2 is not set
56# CONFIG_RELAY is not set
57# CONFIG_NAMESPACES is not set
58# CONFIG_BLK_DEV_INITRD is not set
59CONFIG_CC_OPTIMIZE_FOR_SIZE=y
60CONFIG_SYSCTL=y
61CONFIG_EMBEDDED=y
62CONFIG_UID16=y
63CONFIG_SYSCTL_SYSCALL=y
64CONFIG_KALLSYMS=y
65CONFIG_KALLSYMS_EXTRA_PASS=y
66# CONFIG_HOTPLUG is not set
67CONFIG_PRINTK=y
68CONFIG_BUG=y
69# CONFIG_ELF_CORE is not set
70CONFIG_BASE_FULL=y
71CONFIG_FUTEX=y
72# CONFIG_EPOLL is not set
73# CONFIG_SIGNALFD is not set
74# CONFIG_TIMERFD is not set
75# CONFIG_EVENTFD is not set
76CONFIG_SHMEM=y
77# CONFIG_AIO is not set
78
79#
80# Performance Counters
81#
82# CONFIG_VM_EVENT_COUNTERS is not set
83# CONFIG_SLUB_DEBUG is not set
84# CONFIG_STRIP_ASM_SYMS is not set
85# CONFIG_COMPAT_BRK is not set
86# CONFIG_SLAB is not set
87CONFIG_SLUB=y
88# CONFIG_SLOB is not set
89# CONFIG_PROFILING is not set
90# CONFIG_MARKERS is not set
91CONFIG_HAVE_OPROFILE=y
92# CONFIG_KPROBES is not set
93CONFIG_HAVE_KPROBES=y
94CONFIG_HAVE_KRETPROBES=y
95
96#
97# GCOV-based kernel profiling
98#
99# CONFIG_SLOW_WORK is not set
100CONFIG_HAVE_GENERIC_DMA_COHERENT=y
101CONFIG_RT_MUTEXES=y
102CONFIG_BASE_SMALL=0
103CONFIG_MODULES=y
104# CONFIG_MODULE_FORCE_LOAD is not set
105CONFIG_MODULE_UNLOAD=y
106# CONFIG_MODULE_FORCE_UNLOAD is not set
107# CONFIG_MODVERSIONS is not set
108# CONFIG_MODULE_SRCVERSION_ALL is not set
109CONFIG_BLOCK=y
110CONFIG_LBDAF=y
111# CONFIG_BLK_DEV_BSG is not set
112# CONFIG_BLK_DEV_INTEGRITY is not set
113
114#
115# IO Schedulers
116#
117CONFIG_IOSCHED_NOOP=y
118# CONFIG_IOSCHED_AS is not set
119# CONFIG_IOSCHED_DEADLINE is not set
120# CONFIG_IOSCHED_CFQ is not set
121# CONFIG_DEFAULT_AS is not set
122# CONFIG_DEFAULT_DEADLINE is not set
123# CONFIG_DEFAULT_CFQ is not set
124CONFIG_DEFAULT_NOOP=y
125CONFIG_DEFAULT_IOSCHED="noop"
126# CONFIG_FREEZER is not set
127
128#
129# System Type
130#
131# CONFIG_ARCH_AAEC2000 is not set
132# CONFIG_ARCH_INTEGRATOR is not set
133# CONFIG_ARCH_REALVIEW is not set
134# CONFIG_ARCH_VERSATILE is not set
135# CONFIG_ARCH_AT91 is not set
136# CONFIG_ARCH_CLPS711X is not set
137# CONFIG_ARCH_GEMINI is not set
138# CONFIG_ARCH_EBSA110 is not set
139# CONFIG_ARCH_EP93XX is not set
140# CONFIG_ARCH_FOOTBRIDGE is not set
141# CONFIG_ARCH_MXC is not set
142# CONFIG_ARCH_STMP3XXX is not set
143# CONFIG_ARCH_NETX is not set
144# CONFIG_ARCH_H720X is not set
145# CONFIG_ARCH_IOP13XX is not set
146# CONFIG_ARCH_IOP32X is not set
147# CONFIG_ARCH_IOP33X is not set
148# CONFIG_ARCH_IXP23XX is not set
149# CONFIG_ARCH_IXP2000 is not set
150# CONFIG_ARCH_IXP4XX is not set
151# CONFIG_ARCH_L7200 is not set
152# CONFIG_ARCH_KIRKWOOD is not set
153# CONFIG_ARCH_LOKI is not set
154# CONFIG_ARCH_MV78XX0 is not set
155# CONFIG_ARCH_ORION5X is not set
156# CONFIG_ARCH_MMP is not set
157# CONFIG_ARCH_KS8695 is not set
158# CONFIG_ARCH_NS9XXX is not set
159# CONFIG_ARCH_W90X900 is not set
160# CONFIG_ARCH_PNX4008 is not set
161# CONFIG_ARCH_PXA is not set
162# CONFIG_ARCH_MSM is not set
163# CONFIG_ARCH_RPC is not set
164# CONFIG_ARCH_SA1100 is not set
165# CONFIG_ARCH_S3C2410 is not set
166# CONFIG_ARCH_S3C64XX is not set
167# CONFIG_ARCH_SHARK is not set
168# CONFIG_ARCH_LH7A40X is not set
169# CONFIG_ARCH_U300 is not set
170# CONFIG_ARCH_DAVINCI is not set
171# CONFIG_ARCH_OMAP is not set
172CONFIG_ARCH_BCMRING=y
173# CONFIG_ARCH_FPGA11107 is not set
174CONFIG_ARCH_BCM11107=y
175
176#
177# BCMRING Options
178#
179CONFIG_BCM_ZRELADDR=0x8000
180
181#
182# Processor Type
183#
184CONFIG_CPU_32=y
185CONFIG_CPU_V6=y
186CONFIG_CPU_32v6K=y
187CONFIG_CPU_32v6=y
188CONFIG_CPU_ABRT_EV6=y
189CONFIG_CPU_PABRT_NOIFAR=y
190CONFIG_CPU_CACHE_V6=y
191CONFIG_CPU_CACHE_VIPT=y
192CONFIG_CPU_COPY_V6=y
193CONFIG_CPU_TLB_V6=y
194CONFIG_CPU_HAS_ASID=y
195CONFIG_CPU_CP15=y
196CONFIG_CPU_CP15_MMU=y
197
198#
199# Processor Features
200#
201CONFIG_ARM_THUMB=y
202# CONFIG_CPU_ICACHE_DISABLE is not set
203# CONFIG_CPU_DCACHE_DISABLE is not set
204# CONFIG_CPU_BPREDICT_DISABLE is not set
205# CONFIG_ARM_ERRATA_411920 is not set
206CONFIG_COMMON_CLKDEV=y
207
208#
209# Bus support
210#
211CONFIG_ARM_AMBA=y
212# CONFIG_PCI_SYSCALL is not set
213# CONFIG_ARCH_SUPPORTS_MSI is not set
214
215#
216# Kernel Features
217#
218CONFIG_TICK_ONESHOT=y
219CONFIG_NO_HZ=y
220# CONFIG_HIGH_RES_TIMERS is not set
221CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
222CONFIG_VMSPLIT_3G=y
223# CONFIG_VMSPLIT_2G is not set
224# CONFIG_VMSPLIT_1G is not set
225CONFIG_PAGE_OFFSET=0xC0000000
226CONFIG_PREEMPT=y
227CONFIG_HZ=100
228CONFIG_AEABI=y
229# CONFIG_OABI_COMPAT is not set
230# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
231# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
232# CONFIG_HIGHMEM is not set
233CONFIG_SELECT_MEMORY_MODEL=y
234CONFIG_FLATMEM_MANUAL=y
235# CONFIG_DISCONTIGMEM_MANUAL is not set
236# CONFIG_SPARSEMEM_MANUAL is not set
237CONFIG_FLATMEM=y
238CONFIG_FLAT_NODE_MEM_MAP=y
239CONFIG_PAGEFLAGS_EXTENDED=y
240CONFIG_SPLIT_PTLOCK_CPUS=4
241# CONFIG_PHYS_ADDR_T_64BIT is not set
242CONFIG_ZONE_DMA_FLAG=0
243CONFIG_VIRT_TO_BUS=y
244CONFIG_HAVE_MLOCK=y
245CONFIG_HAVE_MLOCKED_PAGE_BIT=y
246CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
247CONFIG_ALIGNMENT_TRAP=y
248CONFIG_UACCESS_WITH_MEMCPY=y
249
250#
251# Boot options
252#
253CONFIG_ZBOOT_ROM_TEXT=0x0e000000
254CONFIG_ZBOOT_ROM_BSS=0x0ea00000
255CONFIG_ZBOOT_ROM=y
256CONFIG_CMDLINE=""
257# CONFIG_KEXEC is not set
258
259#
260# CPU Power Management
261#
262# CONFIG_CPU_IDLE is not set
263
264#
265# Floating point emulation
266#
267
268#
269# At least one emulation must be selected
270#
271# CONFIG_VFP is not set
272
273#
274# Userspace binary formats
275#
276CONFIG_BINFMT_ELF=y
277CONFIG_HAVE_AOUT=y
278# CONFIG_BINFMT_AOUT is not set
279# CONFIG_BINFMT_MISC is not set
280
281#
282# Power management options
283#
284# CONFIG_PM is not set
285CONFIG_ARCH_SUSPEND_POSSIBLE=y
286CONFIG_NET=y
287
288#
289# Networking options
290#
291# CONFIG_PACKET is not set
292# CONFIG_UNIX is not set
293# CONFIG_NET_KEY is not set
294# CONFIG_INET is not set
295# CONFIG_NETWORK_SECMARK is not set
296# CONFIG_NETFILTER is not set
297# CONFIG_ATM is not set
298# CONFIG_BRIDGE is not set
299# CONFIG_NET_DSA is not set
300# CONFIG_VLAN_8021Q is not set
301# CONFIG_DECNET is not set
302# CONFIG_LLC2 is not set
303# CONFIG_IPX is not set
304# CONFIG_ATALK is not set
305# CONFIG_X25 is not set
306# CONFIG_LAPB is not set
307# CONFIG_WAN_ROUTER is not set
308# CONFIG_PHONET is not set
309# CONFIG_IEEE802154 is not set
310# CONFIG_NET_SCHED is not set
311# CONFIG_DCB is not set
312
313#
314# Network testing
315#
316# CONFIG_NET_PKTGEN is not set
317# CONFIG_HAMRADIO is not set
318# CONFIG_CAN is not set
319# CONFIG_IRDA is not set
320# CONFIG_BT is not set
321# CONFIG_WIRELESS is not set
322# CONFIG_WIMAX is not set
323# CONFIG_RFKILL is not set
324# CONFIG_NET_9P is not set
325
326#
327# Device Drivers
328#
329
330#
331# Generic Driver Options
332#
333CONFIG_STANDALONE=y
334CONFIG_PREVENT_FIRMWARE_BUILD=y
335# CONFIG_SYS_HYPERVISOR is not set
336# CONFIG_CONNECTOR is not set
337CONFIG_MTD=y
338# CONFIG_MTD_DEBUG is not set
339CONFIG_MTD_CONCAT=y
340CONFIG_MTD_PARTITIONS=y
341# CONFIG_MTD_TESTS is not set
342# CONFIG_MTD_REDBOOT_PARTS is not set
343CONFIG_MTD_CMDLINE_PARTS=y
344# CONFIG_MTD_AFS_PARTS is not set
345# CONFIG_MTD_AR7_PARTS is not set
346
347#
348# User Modules And Translation Layers
349#
350CONFIG_MTD_CHAR=y
351CONFIG_MTD_BLKDEVS=y
352CONFIG_MTD_BLOCK=y
353# CONFIG_FTL is not set
354# CONFIG_NFTL is not set
355# CONFIG_INFTL is not set
356# CONFIG_RFD_FTL is not set
357# CONFIG_SSFDC is not set
358# CONFIG_MTD_OOPS is not set
359
360#
361# RAM/ROM/Flash chip drivers
362#
363CONFIG_MTD_CFI=y
364# CONFIG_MTD_JEDECPROBE is not set
365CONFIG_MTD_GEN_PROBE=y
366CONFIG_MTD_CFI_ADV_OPTIONS=y
367CONFIG_MTD_CFI_NOSWAP=y
368# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
369# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
370CONFIG_MTD_CFI_GEOMETRY=y
371CONFIG_MTD_MAP_BANK_WIDTH_1=y
372CONFIG_MTD_MAP_BANK_WIDTH_2=y
373CONFIG_MTD_MAP_BANK_WIDTH_4=y
374# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
375# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
376# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
377CONFIG_MTD_CFI_I1=y
378# CONFIG_MTD_CFI_I2 is not set
379# CONFIG_MTD_CFI_I4 is not set
380# CONFIG_MTD_CFI_I8 is not set
381# CONFIG_MTD_OTP is not set
382# CONFIG_MTD_CFI_INTELEXT is not set
383# CONFIG_MTD_CFI_AMDSTD is not set
384# CONFIG_MTD_CFI_STAA is not set
385CONFIG_MTD_CFI_UTIL=y
386# CONFIG_MTD_RAM is not set
387# CONFIG_MTD_ROM is not set
388# CONFIG_MTD_ABSENT is not set
389
390#
391# Mapping drivers for chip access
392#
393# CONFIG_MTD_COMPLEX_MAPPINGS is not set
394# CONFIG_MTD_PHYSMAP is not set
395# CONFIG_MTD_ARM_INTEGRATOR is not set
396# CONFIG_MTD_PLATRAM is not set
397
398#
399# Self-contained MTD device drivers
400#
401# CONFIG_MTD_SLRAM is not set
402# CONFIG_MTD_PHRAM is not set
403# CONFIG_MTD_MTDRAM is not set
404# CONFIG_MTD_BLOCK2MTD is not set
405
406#
407# Disk-On-Chip Device Drivers
408#
409# CONFIG_MTD_DOC2000 is not set
410# CONFIG_MTD_DOC2001 is not set
411# CONFIG_MTD_DOC2001PLUS is not set
412CONFIG_MTD_NAND=y
413CONFIG_MTD_NAND_VERIFY_WRITE=y
414# CONFIG_MTD_NAND_ECC_SMC is not set
415# CONFIG_MTD_NAND_MUSEUM_IDS is not set
416CONFIG_MTD_NAND_IDS=y
417CONFIG_MTD_NAND_BCM_UMI=y
418CONFIG_MTD_NAND_BCM_UMI_HWCS=y
419# CONFIG_MTD_NAND_DISKONCHIP is not set
420# CONFIG_MTD_NAND_NANDSIM is not set
421# CONFIG_MTD_NAND_PLATFORM is not set
422# CONFIG_MTD_ONENAND is not set
423
424#
425# LPDDR flash memory drivers
426#
427# CONFIG_MTD_LPDDR is not set
428
429#
430# UBI - Unsorted block images
431#
432# CONFIG_MTD_UBI is not set
433# CONFIG_PARPORT is not set
434CONFIG_BLK_DEV=y
435# CONFIG_BLK_DEV_COW_COMMON is not set
436# CONFIG_BLK_DEV_LOOP is not set
437# CONFIG_BLK_DEV_NBD is not set
438# CONFIG_BLK_DEV_RAM is not set
439# CONFIG_CDROM_PKTCDVD is not set
440# CONFIG_ATA_OVER_ETH is not set
441# CONFIG_MISC_DEVICES is not set
442CONFIG_HAVE_IDE=y
443# CONFIG_IDE is not set
444
445#
446# SCSI device support
447#
448# CONFIG_RAID_ATTRS is not set
449# CONFIG_SCSI is not set
450# CONFIG_SCSI_DMA is not set
451# CONFIG_SCSI_NETLINK is not set
452# CONFIG_ATA is not set
453# CONFIG_MD is not set
454# CONFIG_NETDEVICES is not set
455# CONFIG_ISDN is not set
456
457#
458# Input device support
459#
460CONFIG_INPUT=y
461# CONFIG_INPUT_FF_MEMLESS is not set
462# CONFIG_INPUT_POLLDEV is not set
463
464#
465# Userland interfaces
466#
467# CONFIG_INPUT_MOUSEDEV is not set
468# CONFIG_INPUT_JOYDEV is not set
469# CONFIG_INPUT_EVDEV is not set
470# CONFIG_INPUT_EVBUG is not set
471
472#
473# Input Device Drivers
474#
475# CONFIG_INPUT_KEYBOARD is not set
476# CONFIG_INPUT_MOUSE is not set
477# CONFIG_INPUT_JOYSTICK is not set
478# CONFIG_INPUT_TABLET is not set
479# CONFIG_INPUT_TOUCHSCREEN is not set
480# CONFIG_INPUT_MISC is not set
481
482#
483# Hardware I/O ports
484#
485# CONFIG_SERIO is not set
486# CONFIG_GAMEPORT is not set
487
488#
489# Character devices
490#
491CONFIG_VT=y
492# CONFIG_CONSOLE_TRANSLATIONS is not set
493CONFIG_VT_CONSOLE=y
494CONFIG_HW_CONSOLE=y
495# CONFIG_VT_HW_CONSOLE_BINDING is not set
496# CONFIG_DEVKMEM is not set
497# CONFIG_SERIAL_NONSTANDARD is not set
498
499#
500# Serial drivers
501#
502# CONFIG_SERIAL_8250 is not set
503
504#
505# Non-8250 serial port support
506#
507# CONFIG_SERIAL_AMBA_PL010 is not set
508CONFIG_SERIAL_AMBA_PL011=y
509CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
510CONFIG_SERIAL_CORE=y
511CONFIG_SERIAL_CORE_CONSOLE=y
512CONFIG_UNIX98_PTYS=y
513# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
514CONFIG_LEGACY_PTYS=y
515CONFIG_LEGACY_PTY_COUNT=64
516# CONFIG_IPMI_HANDLER is not set
517# CONFIG_HW_RANDOM is not set
518# CONFIG_R3964 is not set
519# CONFIG_RAW_DRIVER is not set
520# CONFIG_TCG_TPM is not set
521# CONFIG_I2C is not set
522# CONFIG_SPI is not set
523CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
524# CONFIG_GPIOLIB is not set
525# CONFIG_W1 is not set
526# CONFIG_POWER_SUPPLY is not set
527# CONFIG_HWMON is not set
528# CONFIG_THERMAL is not set
529# CONFIG_THERMAL_HWMON is not set
530# CONFIG_WATCHDOG is not set
531CONFIG_SSB_POSSIBLE=y
532
533#
534# Sonics Silicon Backplane
535#
536# CONFIG_SSB is not set
537
538#
539# Multifunction device drivers
540#
541# CONFIG_MFD_CORE is not set
542# CONFIG_MFD_SM501 is not set
543# CONFIG_HTC_PASIC3 is not set
544# CONFIG_MFD_TMIO is not set
545# CONFIG_MEDIA_SUPPORT is not set
546
547#
548# Graphics support
549#
550# CONFIG_VGASTATE is not set
551# CONFIG_VIDEO_OUTPUT_CONTROL is not set
552# CONFIG_FB is not set
553# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
554
555#
556# Display device support
557#
558# CONFIG_DISPLAY_SUPPORT is not set
559
560#
561# Console display driver support
562#
563# CONFIG_VGA_CONSOLE is not set
564CONFIG_DUMMY_CONSOLE=y
565# CONFIG_SOUND is not set
566# CONFIG_HID_SUPPORT is not set
567# CONFIG_USB_SUPPORT is not set
568# CONFIG_MMC is not set
569# CONFIG_MEMSTICK is not set
570# CONFIG_ACCESSIBILITY is not set
571# CONFIG_NEW_LEDS is not set
572CONFIG_RTC_LIB=y
573# CONFIG_RTC_CLASS is not set
574# CONFIG_DMADEVICES is not set
575# CONFIG_AUXDISPLAY is not set
576# CONFIG_REGULATOR is not set
577# CONFIG_UIO is not set
578# CONFIG_STAGING is not set
579
580#
581# File systems
582#
583# CONFIG_EXT2_FS is not set
584# CONFIG_EXT3_FS is not set
585# CONFIG_EXT4_FS is not set
586# CONFIG_REISERFS_FS is not set
587# CONFIG_JFS_FS is not set
588CONFIG_FS_POSIX_ACL=y
589# CONFIG_XFS_FS is not set
590# CONFIG_GFS2_FS is not set
591# CONFIG_OCFS2_FS is not set
592# CONFIG_BTRFS_FS is not set
593# CONFIG_FILE_LOCKING is not set
594# CONFIG_FSNOTIFY is not set
595# CONFIG_INOTIFY is not set
596# CONFIG_QUOTA is not set
597# CONFIG_AUTOFS_FS is not set
598# CONFIG_AUTOFS4_FS is not set
599# CONFIG_FUSE_FS is not set
600
601#
602# Caches
603#
604# CONFIG_FSCACHE is not set
605
606#
607# CD-ROM/DVD Filesystems
608#
609# CONFIG_ISO9660_FS is not set
610# CONFIG_UDF_FS is not set
611
612#
613# DOS/FAT/NT Filesystems
614#
615# CONFIG_MSDOS_FS is not set
616# CONFIG_VFAT_FS is not set
617# CONFIG_NTFS_FS is not set
618
619#
620# Pseudo filesystems
621#
622CONFIG_PROC_FS=y
623CONFIG_PROC_SYSCTL=y
624# CONFIG_PROC_PAGE_MONITOR is not set
625CONFIG_SYSFS=y
626CONFIG_TMPFS=y
627# CONFIG_TMPFS_POSIX_ACL is not set
628# CONFIG_HUGETLB_PAGE is not set
629# CONFIG_CONFIGFS_FS is not set
630CONFIG_MISC_FILESYSTEMS=y
631# CONFIG_ADFS_FS is not set
632# CONFIG_AFFS_FS is not set
633# CONFIG_HFS_FS is not set
634# CONFIG_HFSPLUS_FS is not set
635# CONFIG_BEFS_FS is not set
636# CONFIG_BFS_FS is not set
637# CONFIG_EFS_FS is not set
638CONFIG_JFFS2_FS=y
639CONFIG_JFFS2_FS_DEBUG=0
640CONFIG_JFFS2_FS_WRITEBUFFER=y
641# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
642CONFIG_JFFS2_SUMMARY=y
643CONFIG_JFFS2_FS_XATTR=y
644CONFIG_JFFS2_FS_POSIX_ACL=y
645# CONFIG_JFFS2_FS_SECURITY is not set
646# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
647CONFIG_JFFS2_ZLIB=y
648# CONFIG_JFFS2_LZO is not set
649CONFIG_JFFS2_RTIME=y
650# CONFIG_JFFS2_RUBIN is not set
651# CONFIG_CRAMFS is not set
652# CONFIG_SQUASHFS is not set
653# CONFIG_VXFS_FS is not set
654# CONFIG_MINIX_FS is not set
655# CONFIG_OMFS_FS is not set
656# CONFIG_HPFS_FS is not set
657# CONFIG_QNX4FS_FS is not set
658# CONFIG_ROMFS_FS is not set
659# CONFIG_SYSV_FS is not set
660# CONFIG_UFS_FS is not set
661# CONFIG_NILFS2_FS is not set
662# CONFIG_NETWORK_FILESYSTEMS is not set
663
664#
665# Partition Types
666#
667# CONFIG_PARTITION_ADVANCED is not set
668CONFIG_MSDOS_PARTITION=y
669# CONFIG_NLS is not set
670
671#
672# Kernel hacking
673#
674# CONFIG_PRINTK_TIME is not set
675# CONFIG_ENABLE_WARN_DEPRECATED is not set
676CONFIG_ENABLE_MUST_CHECK=y
677CONFIG_FRAME_WARN=1024
678CONFIG_MAGIC_SYSRQ=y
679# CONFIG_UNUSED_SYMBOLS is not set
680# CONFIG_DEBUG_FS is not set
681CONFIG_HEADERS_CHECK=y
682# CONFIG_DEBUG_KERNEL is not set
683# CONFIG_DEBUG_BUGVERBOSE is not set
684# CONFIG_DEBUG_MEMORY_INIT is not set
685CONFIG_FRAME_POINTER=y
686# CONFIG_RCU_CPU_STALL_DETECTOR is not set
687# CONFIG_LATENCYTOP is not set
688# CONFIG_SYSCTL_SYSCALL_CHECK is not set
689CONFIG_HAVE_FUNCTION_TRACER=y
690CONFIG_TRACING_SUPPORT=y
691# CONFIG_FTRACE is not set
692# CONFIG_BUILD_DOCSRC is not set
693# CONFIG_SAMPLES is not set
694CONFIG_HAVE_ARCH_KGDB=y
695# CONFIG_ARM_UNWIND is not set
696# CONFIG_DEBUG_USER is not set
697
698#
699# Security options
700#
701# CONFIG_KEYS is not set
702# CONFIG_SECURITY is not set
703# CONFIG_SECURITYFS is not set
704# CONFIG_SECURITY_FILE_CAPABILITIES is not set
705# CONFIG_CRYPTO is not set
706# CONFIG_BINARY_PRINTF is not set
707
708#
709# Library routines
710#
711CONFIG_BITREVERSE=y
712CONFIG_GENERIC_FIND_LAST_BIT=y
713# CONFIG_CRC_CCITT is not set
714# CONFIG_CRC16 is not set
715# CONFIG_CRC_T10DIF is not set
716# CONFIG_CRC_ITU_T is not set
717CONFIG_CRC32=y
718# CONFIG_CRC7 is not set
719# CONFIG_LIBCRC32C is not set
720CONFIG_ZLIB_INFLATE=y
721CONFIG_ZLIB_DEFLATE=y
722CONFIG_HAS_IOMEM=y
723CONFIG_HAS_IOPORT=y
724CONFIG_HAS_DMA=y
725CONFIG_NLATTR=y
diff --git a/arch/arm/configs/cpu9260_defconfig b/arch/arm/configs/cpu9260_defconfig
new file mode 100644
index 000000000000..601e7f3d5e97
--- /dev/null
+++ b/arch/arm/configs/cpu9260_defconfig
@@ -0,0 +1,1338 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.31-rc3
4# Tue Jul 14 14:57:55 2009
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12CONFIG_GENERIC_HARDIRQS=y
13CONFIG_STACKTRACE_SUPPORT=y
14CONFIG_HAVE_LATENCYTOP_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20CONFIG_GENERIC_HWEIGHT=y
21CONFIG_GENERIC_CALIBRATE_DELAY=y
22CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
23CONFIG_VECTORS_BASE=0xffff0000
24CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
25CONFIG_CONSTRUCTORS=y
26
27#
28# General setup
29#
30CONFIG_EXPERIMENTAL=y
31CONFIG_BROKEN_ON_SMP=y
32CONFIG_LOCK_KERNEL=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36# CONFIG_SWAP is not set
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39# CONFIG_POSIX_MQUEUE is not set
40# CONFIG_BSD_PROCESS_ACCT is not set
41# CONFIG_TASKSTATS is not set
42# CONFIG_AUDIT is not set
43
44#
45# RCU Subsystem
46#
47CONFIG_CLASSIC_RCU=y
48# CONFIG_TREE_RCU is not set
49# CONFIG_PREEMPT_RCU is not set
50# CONFIG_TREE_RCU_TRACE is not set
51# CONFIG_PREEMPT_RCU_TRACE is not set
52# CONFIG_IKCONFIG is not set
53CONFIG_LOG_BUF_SHIFT=14
54# CONFIG_GROUP_SCHED is not set
55# CONFIG_CGROUPS is not set
56CONFIG_SYSFS_DEPRECATED=y
57CONFIG_SYSFS_DEPRECATED_V2=y
58# CONFIG_RELAY is not set
59CONFIG_NAMESPACES=y
60# CONFIG_UTS_NS is not set
61# CONFIG_IPC_NS is not set
62# CONFIG_USER_NS is not set
63# CONFIG_PID_NS is not set
64# CONFIG_NET_NS is not set
65# CONFIG_BLK_DEV_INITRD is not set
66CONFIG_CC_OPTIMIZE_FOR_SIZE=y
67CONFIG_SYSCTL=y
68CONFIG_ANON_INODES=y
69# CONFIG_EMBEDDED is not set
70CONFIG_UID16=y
71CONFIG_SYSCTL_SYSCALL=y
72CONFIG_KALLSYMS=y
73# CONFIG_KALLSYMS_EXTRA_PASS is not set
74CONFIG_HOTPLUG=y
75CONFIG_PRINTK=y
76CONFIG_BUG=y
77CONFIG_ELF_CORE=y
78CONFIG_BASE_FULL=y
79CONFIG_FUTEX=y
80CONFIG_EPOLL=y
81CONFIG_SIGNALFD=y
82CONFIG_TIMERFD=y
83CONFIG_EVENTFD=y
84CONFIG_SHMEM=y
85CONFIG_AIO=y
86
87#
88# Performance Counters
89#
90CONFIG_VM_EVENT_COUNTERS=y
91CONFIG_SLUB_DEBUG=y
92# CONFIG_STRIP_ASM_SYMS is not set
93CONFIG_COMPAT_BRK=y
94# CONFIG_SLAB is not set
95CONFIG_SLUB=y
96# CONFIG_SLOB is not set
97# CONFIG_PROFILING is not set
98# CONFIG_MARKERS is not set
99CONFIG_HAVE_OPROFILE=y
100# CONFIG_KPROBES is not set
101CONFIG_HAVE_KPROBES=y
102CONFIG_HAVE_KRETPROBES=y
103CONFIG_HAVE_CLK=y
104
105#
106# GCOV-based kernel profiling
107#
108# CONFIG_SLOW_WORK is not set
109CONFIG_HAVE_GENERIC_DMA_COHERENT=y
110CONFIG_SLABINFO=y
111CONFIG_RT_MUTEXES=y
112CONFIG_BASE_SMALL=0
113CONFIG_MODULES=y
114# CONFIG_MODULE_FORCE_LOAD is not set
115CONFIG_MODULE_UNLOAD=y
116# CONFIG_MODULE_FORCE_UNLOAD is not set
117# CONFIG_MODVERSIONS is not set
118# CONFIG_MODULE_SRCVERSION_ALL is not set
119CONFIG_BLOCK=y
120CONFIG_LBDAF=y
121# CONFIG_BLK_DEV_BSG is not set
122# CONFIG_BLK_DEV_INTEGRITY is not set
123
124#
125# IO Schedulers
126#
127CONFIG_IOSCHED_NOOP=y
128# CONFIG_IOSCHED_AS is not set
129CONFIG_IOSCHED_DEADLINE=y
130# CONFIG_IOSCHED_CFQ is not set
131# CONFIG_DEFAULT_AS is not set
132CONFIG_DEFAULT_DEADLINE=y
133# CONFIG_DEFAULT_CFQ is not set
134# CONFIG_DEFAULT_NOOP is not set
135CONFIG_DEFAULT_IOSCHED="deadline"
136# CONFIG_FREEZER is not set
137
138#
139# System Type
140#
141# CONFIG_ARCH_AAEC2000 is not set
142# CONFIG_ARCH_INTEGRATOR is not set
143# CONFIG_ARCH_REALVIEW is not set
144# CONFIG_ARCH_VERSATILE is not set
145CONFIG_ARCH_AT91=y
146# CONFIG_ARCH_CLPS711X is not set
147# CONFIG_ARCH_GEMINI is not set
148# CONFIG_ARCH_EBSA110 is not set
149# CONFIG_ARCH_EP93XX is not set
150# CONFIG_ARCH_FOOTBRIDGE is not set
151# CONFIG_ARCH_MXC is not set
152# CONFIG_ARCH_STMP3XXX is not set
153# CONFIG_ARCH_NETX is not set
154# CONFIG_ARCH_H720X is not set
155# CONFIG_ARCH_IOP13XX is not set
156# CONFIG_ARCH_IOP32X is not set
157# CONFIG_ARCH_IOP33X is not set
158# CONFIG_ARCH_IXP23XX is not set
159# CONFIG_ARCH_IXP2000 is not set
160# CONFIG_ARCH_IXP4XX is not set
161# CONFIG_ARCH_L7200 is not set
162# CONFIG_ARCH_KIRKWOOD is not set
163# CONFIG_ARCH_LOKI is not set
164# CONFIG_ARCH_MV78XX0 is not set
165# CONFIG_ARCH_ORION5X is not set
166# CONFIG_ARCH_MMP is not set
167# CONFIG_ARCH_KS8695 is not set
168# CONFIG_ARCH_NS9XXX is not set
169# CONFIG_ARCH_W90X900 is not set
170# CONFIG_ARCH_PNX4008 is not set
171# CONFIG_ARCH_PXA is not set
172# CONFIG_ARCH_MSM is not set
173# CONFIG_ARCH_RPC is not set
174# CONFIG_ARCH_SA1100 is not set
175# CONFIG_ARCH_S3C2410 is not set
176# CONFIG_ARCH_S3C64XX is not set
177# CONFIG_ARCH_SHARK is not set
178# CONFIG_ARCH_LH7A40X is not set
179# CONFIG_ARCH_U300 is not set
180# CONFIG_ARCH_DAVINCI is not set
181# CONFIG_ARCH_OMAP is not set
182
183#
184# Atmel AT91 System-on-Chip
185#
186# CONFIG_ARCH_AT91RM9200 is not set
187CONFIG_ARCH_AT91SAM9260=y
188# CONFIG_ARCH_AT91SAM9261 is not set
189# CONFIG_ARCH_AT91SAM9263 is not set
190# CONFIG_ARCH_AT91SAM9RL is not set
191# CONFIG_ARCH_AT91SAM9G20 is not set
192# CONFIG_ARCH_AT91CAP9 is not set
193# CONFIG_ARCH_AT91X40 is not set
194CONFIG_AT91_PMC_UNIT=y
195
196#
197# AT91SAM9260 Variants
198#
199# CONFIG_ARCH_AT91SAM9260_SAM9XE is not set
200
201#
202# AT91SAM9260 / AT91SAM9XE Board Type
203#
204# CONFIG_MACH_AT91SAM9260EK is not set
205# CONFIG_MACH_CAM60 is not set
206# CONFIG_MACH_SAM9_L9260 is not set
207# CONFIG_MACH_AFEB9260 is not set
208# CONFIG_MACH_USB_A9260 is not set
209# CONFIG_MACH_QIL_A9260 is not set
210CONFIG_MACH_CPU9260=y
211
212#
213# AT91 Board Options
214#
215
216#
217# AT91 Feature Selections
218#
219# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
220CONFIG_AT91_TIMER_HZ=100
221CONFIG_AT91_EARLY_DBGU=y
222# CONFIG_AT91_EARLY_USART0 is not set
223# CONFIG_AT91_EARLY_USART1 is not set
224# CONFIG_AT91_EARLY_USART2 is not set
225# CONFIG_AT91_EARLY_USART3 is not set
226# CONFIG_AT91_EARLY_USART4 is not set
227# CONFIG_AT91_EARLY_USART5 is not set
228
229#
230# Processor Type
231#
232CONFIG_CPU_32=y
233CONFIG_CPU_ARM926T=y
234CONFIG_CPU_32v5=y
235CONFIG_CPU_ABRT_EV5TJ=y
236CONFIG_CPU_PABRT_NOIFAR=y
237CONFIG_CPU_CACHE_VIVT=y
238CONFIG_CPU_COPY_V4WB=y
239CONFIG_CPU_TLB_V4WBI=y
240CONFIG_CPU_CP15=y
241CONFIG_CPU_CP15_MMU=y
242
243#
244# Processor Features
245#
246# CONFIG_ARM_THUMB is not set
247# CONFIG_CPU_ICACHE_DISABLE is not set
248# CONFIG_CPU_DCACHE_DISABLE is not set
249# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
250# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
251
252#
253# Bus support
254#
255# CONFIG_PCI_SYSCALL is not set
256# CONFIG_ARCH_SUPPORTS_MSI is not set
257# CONFIG_PCCARD is not set
258
259#
260# Kernel Features
261#
262# CONFIG_NO_HZ is not set
263# CONFIG_HIGH_RES_TIMERS is not set
264CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
265CONFIG_VMSPLIT_3G=y
266# CONFIG_VMSPLIT_2G is not set
267# CONFIG_VMSPLIT_1G is not set
268CONFIG_PAGE_OFFSET=0xC0000000
269CONFIG_PREEMPT=y
270CONFIG_HZ=100
271CONFIG_AEABI=y
272CONFIG_OABI_COMPAT=y
273# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
274# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
275# CONFIG_HIGHMEM is not set
276CONFIG_SELECT_MEMORY_MODEL=y
277CONFIG_FLATMEM_MANUAL=y
278# CONFIG_DISCONTIGMEM_MANUAL is not set
279# CONFIG_SPARSEMEM_MANUAL is not set
280CONFIG_FLATMEM=y
281CONFIG_FLAT_NODE_MEM_MAP=y
282CONFIG_PAGEFLAGS_EXTENDED=y
283CONFIG_SPLIT_PTLOCK_CPUS=4096
284# CONFIG_PHYS_ADDR_T_64BIT is not set
285CONFIG_ZONE_DMA_FLAG=0
286CONFIG_VIRT_TO_BUS=y
287CONFIG_HAVE_MLOCK=y
288CONFIG_HAVE_MLOCKED_PAGE_BIT=y
289CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
290# CONFIG_LEDS is not set
291CONFIG_ALIGNMENT_TRAP=y
292# CONFIG_UACCESS_WITH_MEMCPY is not set
293
294#
295# Boot options
296#
297CONFIG_ZBOOT_ROM_TEXT=0x0
298CONFIG_ZBOOT_ROM_BSS=0x0
299CONFIG_CMDLINE=""
300# CONFIG_XIP_KERNEL is not set
301# CONFIG_KEXEC is not set
302
303#
304# CPU Power Management
305#
306# CONFIG_CPU_IDLE is not set
307
308#
309# Floating point emulation
310#
311
312#
313# At least one emulation must be selected
314#
315# CONFIG_FPE_NWFPE is not set
316# CONFIG_FPE_FASTFPE is not set
317# CONFIG_VFP is not set
318
319#
320# Userspace binary formats
321#
322CONFIG_BINFMT_ELF=y
323# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
324CONFIG_HAVE_AOUT=y
325# CONFIG_BINFMT_AOUT is not set
326# CONFIG_BINFMT_MISC is not set
327
328#
329# Power management options
330#
331# CONFIG_PM is not set
332CONFIG_ARCH_SUSPEND_POSSIBLE=y
333CONFIG_NET=y
334
335#
336# Networking options
337#
338CONFIG_PACKET=y
339# CONFIG_PACKET_MMAP is not set
340CONFIG_UNIX=y
341# CONFIG_NET_KEY is not set
342CONFIG_INET=y
343# CONFIG_IP_MULTICAST is not set
344# CONFIG_IP_ADVANCED_ROUTER is not set
345CONFIG_IP_FIB_HASH=y
346CONFIG_IP_PNP=y
347# CONFIG_IP_PNP_DHCP is not set
348# CONFIG_IP_PNP_BOOTP is not set
349# CONFIG_IP_PNP_RARP is not set
350# CONFIG_NET_IPIP is not set
351# CONFIG_NET_IPGRE is not set
352# CONFIG_ARPD is not set
353# CONFIG_SYN_COOKIES is not set
354# CONFIG_INET_AH is not set
355# CONFIG_INET_ESP is not set
356# CONFIG_INET_IPCOMP is not set
357# CONFIG_INET_XFRM_TUNNEL is not set
358# CONFIG_INET_TUNNEL is not set
359# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
360# CONFIG_INET_XFRM_MODE_TUNNEL is not set
361# CONFIG_INET_XFRM_MODE_BEET is not set
362CONFIG_INET_LRO=y
363CONFIG_INET_DIAG=y
364CONFIG_INET_TCP_DIAG=y
365# CONFIG_TCP_CONG_ADVANCED is not set
366CONFIG_TCP_CONG_CUBIC=y
367CONFIG_DEFAULT_TCP_CONG="cubic"
368# CONFIG_TCP_MD5SIG is not set
369# CONFIG_IPV6 is not set
370# CONFIG_NETWORK_SECMARK is not set
371# CONFIG_NETFILTER is not set
372# CONFIG_IP_DCCP is not set
373# CONFIG_IP_SCTP is not set
374# CONFIG_TIPC is not set
375# CONFIG_ATM is not set
376# CONFIG_BRIDGE is not set
377# CONFIG_NET_DSA is not set
378# CONFIG_VLAN_8021Q is not set
379# CONFIG_DECNET is not set
380# CONFIG_LLC2 is not set
381# CONFIG_IPX is not set
382# CONFIG_ATALK is not set
383# CONFIG_X25 is not set
384# CONFIG_LAPB is not set
385# CONFIG_ECONET is not set
386# CONFIG_WAN_ROUTER is not set
387# CONFIG_PHONET is not set
388# CONFIG_IEEE802154 is not set
389# CONFIG_NET_SCHED is not set
390# CONFIG_DCB is not set
391
392#
393# Network testing
394#
395# CONFIG_NET_PKTGEN is not set
396# CONFIG_HAMRADIO is not set
397# CONFIG_CAN is not set
398# CONFIG_IRDA is not set
399# CONFIG_BT is not set
400# CONFIG_AF_RXRPC is not set
401# CONFIG_WIRELESS is not set
402# CONFIG_WIMAX is not set
403# CONFIG_RFKILL is not set
404# CONFIG_NET_9P is not set
405
406#
407# Device Drivers
408#
409
410#
411# Generic Driver Options
412#
413CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
414CONFIG_STANDALONE=y
415CONFIG_PREVENT_FIRMWARE_BUILD=y
416CONFIG_FW_LOADER=y
417CONFIG_FIRMWARE_IN_KERNEL=y
418CONFIG_EXTRA_FIRMWARE=""
419# CONFIG_SYS_HYPERVISOR is not set
420# CONFIG_CONNECTOR is not set
421CONFIG_MTD=y
422# CONFIG_MTD_DEBUG is not set
423# CONFIG_MTD_CONCAT is not set
424CONFIG_MTD_PARTITIONS=y
425# CONFIG_MTD_TESTS is not set
426# CONFIG_MTD_REDBOOT_PARTS is not set
427CONFIG_MTD_CMDLINE_PARTS=y
428# CONFIG_MTD_AFS_PARTS is not set
429# CONFIG_MTD_AR7_PARTS is not set
430
431#
432# User Modules And Translation Layers
433#
434CONFIG_MTD_CHAR=y
435CONFIG_MTD_BLKDEVS=y
436CONFIG_MTD_BLOCK=y
437# CONFIG_FTL is not set
438# CONFIG_NFTL is not set
439# CONFIG_INFTL is not set
440# CONFIG_RFD_FTL is not set
441# CONFIG_SSFDC is not set
442# CONFIG_MTD_OOPS is not set
443
444#
445# RAM/ROM/Flash chip drivers
446#
447CONFIG_MTD_CFI=y
448# CONFIG_MTD_JEDECPROBE is not set
449CONFIG_MTD_GEN_PROBE=y
450# CONFIG_MTD_CFI_ADV_OPTIONS is not set
451CONFIG_MTD_MAP_BANK_WIDTH_1=y
452CONFIG_MTD_MAP_BANK_WIDTH_2=y
453CONFIG_MTD_MAP_BANK_WIDTH_4=y
454# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
455# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
456# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
457CONFIG_MTD_CFI_I1=y
458CONFIG_MTD_CFI_I2=y
459# CONFIG_MTD_CFI_I4 is not set
460# CONFIG_MTD_CFI_I8 is not set
461CONFIG_MTD_CFI_INTELEXT=y
462# CONFIG_MTD_CFI_AMDSTD is not set
463# CONFIG_MTD_CFI_STAA is not set
464CONFIG_MTD_CFI_UTIL=y
465CONFIG_MTD_RAM=y
466# CONFIG_MTD_ROM is not set
467# CONFIG_MTD_ABSENT is not set
468
469#
470# Mapping drivers for chip access
471#
472# CONFIG_MTD_COMPLEX_MAPPINGS is not set
473CONFIG_MTD_PHYSMAP=y
474# CONFIG_MTD_PHYSMAP_COMPAT is not set
475# CONFIG_MTD_ARM_INTEGRATOR is not set
476CONFIG_MTD_PLATRAM=y
477
478#
479# Self-contained MTD device drivers
480#
481# CONFIG_MTD_SLRAM is not set
482# CONFIG_MTD_PHRAM is not set
483# CONFIG_MTD_MTDRAM is not set
484# CONFIG_MTD_BLOCK2MTD is not set
485
486#
487# Disk-On-Chip Device Drivers
488#
489# CONFIG_MTD_DOC2000 is not set
490# CONFIG_MTD_DOC2001 is not set
491# CONFIG_MTD_DOC2001PLUS is not set
492CONFIG_MTD_NAND=y
493# CONFIG_MTD_NAND_VERIFY_WRITE is not set
494# CONFIG_MTD_NAND_ECC_SMC is not set
495# CONFIG_MTD_NAND_MUSEUM_IDS is not set
496# CONFIG_MTD_NAND_GPIO is not set
497CONFIG_MTD_NAND_IDS=y
498# CONFIG_MTD_NAND_DISKONCHIP is not set
499CONFIG_MTD_NAND_ATMEL=y
500CONFIG_MTD_NAND_ATMEL_ECC_HW=y
501# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
502# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
503# CONFIG_MTD_NAND_NANDSIM is not set
504# CONFIG_MTD_NAND_PLATFORM is not set
505# CONFIG_MTD_ALAUDA is not set
506# CONFIG_MTD_ONENAND is not set
507
508#
509# LPDDR flash memory drivers
510#
511# CONFIG_MTD_LPDDR is not set
512
513#
514# UBI - Unsorted block images
515#
516# CONFIG_MTD_UBI is not set
517# CONFIG_PARPORT is not set
518CONFIG_BLK_DEV=y
519# CONFIG_BLK_DEV_COW_COMMON is not set
520CONFIG_BLK_DEV_LOOP=y
521# CONFIG_BLK_DEV_CRYPTOLOOP is not set
522CONFIG_BLK_DEV_NBD=y
523# CONFIG_BLK_DEV_UB is not set
524CONFIG_BLK_DEV_RAM=y
525CONFIG_BLK_DEV_RAM_COUNT=16
526CONFIG_BLK_DEV_RAM_SIZE=4096
527# CONFIG_BLK_DEV_XIP is not set
528# CONFIG_CDROM_PKTCDVD is not set
529# CONFIG_ATA_OVER_ETH is not set
530# CONFIG_MG_DISK is not set
531# CONFIG_MISC_DEVICES is not set
532CONFIG_HAVE_IDE=y
533# CONFIG_IDE is not set
534
535#
536# SCSI device support
537#
538# CONFIG_RAID_ATTRS is not set
539CONFIG_SCSI=y
540CONFIG_SCSI_DMA=y
541# CONFIG_SCSI_TGT is not set
542# CONFIG_SCSI_NETLINK is not set
543CONFIG_SCSI_PROC_FS=y
544
545#
546# SCSI support type (disk, tape, CD-ROM)
547#
548CONFIG_BLK_DEV_SD=y
549# CONFIG_CHR_DEV_ST is not set
550# CONFIG_CHR_DEV_OSST is not set
551# CONFIG_BLK_DEV_SR is not set
552# CONFIG_CHR_DEV_SG is not set
553# CONFIG_CHR_DEV_SCH is not set
554CONFIG_SCSI_MULTI_LUN=y
555# CONFIG_SCSI_CONSTANTS is not set
556# CONFIG_SCSI_LOGGING is not set
557# CONFIG_SCSI_SCAN_ASYNC is not set
558CONFIG_SCSI_WAIT_SCAN=m
559
560#
561# SCSI Transports
562#
563# CONFIG_SCSI_SPI_ATTRS is not set
564# CONFIG_SCSI_FC_ATTRS is not set
565# CONFIG_SCSI_ISCSI_ATTRS is not set
566# CONFIG_SCSI_SAS_LIBSAS is not set
567# CONFIG_SCSI_SRP_ATTRS is not set
568# CONFIG_SCSI_LOWLEVEL is not set
569# CONFIG_SCSI_DH is not set
570# CONFIG_SCSI_OSD_INITIATOR is not set
571# CONFIG_ATA is not set
572# CONFIG_MD is not set
573CONFIG_NETDEVICES=y
574# CONFIG_DUMMY is not set
575# CONFIG_BONDING is not set
576# CONFIG_MACVLAN is not set
577# CONFIG_EQUALIZER is not set
578# CONFIG_TUN is not set
579# CONFIG_VETH is not set
580CONFIG_PHYLIB=y
581
582#
583# MII PHY device drivers
584#
585# CONFIG_MARVELL_PHY is not set
586# CONFIG_DAVICOM_PHY is not set
587# CONFIG_QSEMI_PHY is not set
588# CONFIG_LXT_PHY is not set
589# CONFIG_CICADA_PHY is not set
590# CONFIG_VITESSE_PHY is not set
591CONFIG_SMSC_PHY=y
592# CONFIG_BROADCOM_PHY is not set
593# CONFIG_ICPLUS_PHY is not set
594# CONFIG_REALTEK_PHY is not set
595# CONFIG_NATIONAL_PHY is not set
596# CONFIG_STE10XP is not set
597# CONFIG_LSI_ET1011C_PHY is not set
598# CONFIG_FIXED_PHY is not set
599# CONFIG_MDIO_BITBANG is not set
600CONFIG_NET_ETHERNET=y
601CONFIG_MII=y
602CONFIG_MACB=y
603# CONFIG_AX88796 is not set
604# CONFIG_SMC91X is not set
605# CONFIG_DM9000 is not set
606# CONFIG_ETHOC is not set
607# CONFIG_SMC911X is not set
608# CONFIG_SMSC911X is not set
609# CONFIG_DNET is not set
610# CONFIG_IBM_NEW_EMAC_ZMII is not set
611# CONFIG_IBM_NEW_EMAC_RGMII is not set
612# CONFIG_IBM_NEW_EMAC_TAH is not set
613# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
614# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
615# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
616# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
617# CONFIG_B44 is not set
618# CONFIG_KS8842 is not set
619# CONFIG_NETDEV_1000 is not set
620# CONFIG_NETDEV_10000 is not set
621
622#
623# Wireless LAN
624#
625# CONFIG_WLAN_PRE80211 is not set
626# CONFIG_WLAN_80211 is not set
627
628#
629# Enable WiMAX (Networking options) to see the WiMAX drivers
630#
631
632#
633# USB Network Adapters
634#
635# CONFIG_USB_CATC is not set
636# CONFIG_USB_KAWETH is not set
637# CONFIG_USB_PEGASUS is not set
638# CONFIG_USB_RTL8150 is not set
639# CONFIG_USB_USBNET is not set
640# CONFIG_WAN is not set
641CONFIG_PPP=y
642# CONFIG_PPP_MULTILINK is not set
643# CONFIG_PPP_FILTER is not set
644CONFIG_PPP_ASYNC=y
645# CONFIG_PPP_SYNC_TTY is not set
646CONFIG_PPP_DEFLATE=y
647CONFIG_PPP_BSDCOMP=y
648# CONFIG_PPP_MPPE is not set
649# CONFIG_PPPOE is not set
650# CONFIG_PPPOL2TP is not set
651# CONFIG_SLIP is not set
652CONFIG_SLHC=y
653# CONFIG_NETCONSOLE is not set
654# CONFIG_NETPOLL is not set
655# CONFIG_NET_POLL_CONTROLLER is not set
656# CONFIG_ISDN is not set
657
658#
659# Input device support
660#
661CONFIG_INPUT=y
662# CONFIG_INPUT_FF_MEMLESS is not set
663# CONFIG_INPUT_POLLDEV is not set
664
665#
666# Userland interfaces
667#
668CONFIG_INPUT_MOUSEDEV=y
669# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
670CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
671CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
672# CONFIG_INPUT_JOYDEV is not set
673# CONFIG_INPUT_EVDEV is not set
674# CONFIG_INPUT_EVBUG is not set
675
676#
677# Input Device Drivers
678#
679CONFIG_INPUT_KEYBOARD=y
680# CONFIG_KEYBOARD_ATKBD is not set
681# CONFIG_KEYBOARD_LKKBD is not set
682CONFIG_KEYBOARD_GPIO=y
683# CONFIG_KEYBOARD_MATRIX is not set
684# CONFIG_KEYBOARD_LM8323 is not set
685# CONFIG_KEYBOARD_NEWTON is not set
686# CONFIG_KEYBOARD_STOWAWAY is not set
687# CONFIG_KEYBOARD_SUNKBD is not set
688# CONFIG_KEYBOARD_XTKBD is not set
689# CONFIG_INPUT_MOUSE is not set
690# CONFIG_INPUT_JOYSTICK is not set
691# CONFIG_INPUT_TABLET is not set
692# CONFIG_INPUT_TOUCHSCREEN is not set
693# CONFIG_INPUT_MISC is not set
694
695#
696# Hardware I/O ports
697#
698# CONFIG_SERIO is not set
699# CONFIG_GAMEPORT is not set
700
701#
702# Character devices
703#
704CONFIG_VT=y
705CONFIG_CONSOLE_TRANSLATIONS=y
706CONFIG_VT_CONSOLE=y
707CONFIG_HW_CONSOLE=y
708# CONFIG_VT_HW_CONSOLE_BINDING is not set
709CONFIG_DEVKMEM=y
710# CONFIG_SERIAL_NONSTANDARD is not set
711
712#
713# Serial drivers
714#
715# CONFIG_SERIAL_8250 is not set
716
717#
718# Non-8250 serial port support
719#
720CONFIG_SERIAL_ATMEL=y
721CONFIG_SERIAL_ATMEL_CONSOLE=y
722CONFIG_SERIAL_ATMEL_PDC=y
723# CONFIG_SERIAL_ATMEL_TTYAT is not set
724CONFIG_SERIAL_CORE=y
725CONFIG_SERIAL_CORE_CONSOLE=y
726CONFIG_UNIX98_PTYS=y
727# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
728CONFIG_LEGACY_PTYS=y
729CONFIG_LEGACY_PTY_COUNT=32
730# CONFIG_IPMI_HANDLER is not set
731# CONFIG_HW_RANDOM is not set
732# CONFIG_R3964 is not set
733# CONFIG_RAW_DRIVER is not set
734# CONFIG_TCG_TPM is not set
735CONFIG_I2C=y
736CONFIG_I2C_BOARDINFO=y
737CONFIG_I2C_CHARDEV=y
738CONFIG_I2C_HELPER_AUTO=y
739CONFIG_I2C_ALGOBIT=y
740
741#
742# I2C Hardware Bus support
743#
744
745#
746# I2C system bus drivers (mostly embedded / system-on-chip)
747#
748# CONFIG_I2C_DESIGNWARE is not set
749CONFIG_I2C_GPIO=y
750# CONFIG_I2C_OCORES is not set
751# CONFIG_I2C_SIMTEC is not set
752
753#
754# External I2C/SMBus adapter drivers
755#
756# CONFIG_I2C_PARPORT_LIGHT is not set
757# CONFIG_I2C_TAOS_EVM is not set
758# CONFIG_I2C_TINY_USB is not set
759
760#
761# Other I2C/SMBus bus drivers
762#
763# CONFIG_I2C_PCA_PLATFORM is not set
764# CONFIG_I2C_STUB is not set
765
766#
767# Miscellaneous I2C Chip support
768#
769# CONFIG_DS1682 is not set
770# CONFIG_SENSORS_PCF8574 is not set
771# CONFIG_PCF8575 is not set
772# CONFIG_SENSORS_PCA9539 is not set
773# CONFIG_SENSORS_TSL2550 is not set
774# CONFIG_I2C_DEBUG_CORE is not set
775# CONFIG_I2C_DEBUG_ALGO is not set
776# CONFIG_I2C_DEBUG_BUS is not set
777# CONFIG_I2C_DEBUG_CHIP is not set
778# CONFIG_SPI is not set
779CONFIG_ARCH_REQUIRE_GPIOLIB=y
780CONFIG_GPIOLIB=y
781CONFIG_GPIO_SYSFS=y
782
783#
784# Memory mapped GPIO expanders:
785#
786
787#
788# I2C GPIO expanders:
789#
790# CONFIG_GPIO_MAX732X is not set
791# CONFIG_GPIO_PCA953X is not set
792# CONFIG_GPIO_PCF857X is not set
793
794#
795# PCI GPIO expanders:
796#
797
798#
799# SPI GPIO expanders:
800#
801# CONFIG_W1 is not set
802# CONFIG_POWER_SUPPLY is not set
803# CONFIG_HWMON is not set
804# CONFIG_THERMAL is not set
805# CONFIG_THERMAL_HWMON is not set
806CONFIG_WATCHDOG=y
807CONFIG_WATCHDOG_NOWAYOUT=y
808
809#
810# Watchdog Device Drivers
811#
812# CONFIG_SOFT_WATCHDOG is not set
813CONFIG_AT91SAM9X_WATCHDOG=y
814
815#
816# USB-based Watchdog Cards
817#
818# CONFIG_USBPCWATCHDOG is not set
819CONFIG_SSB_POSSIBLE=y
820
821#
822# Sonics Silicon Backplane
823#
824# CONFIG_SSB is not set
825
826#
827# Multifunction device drivers
828#
829# CONFIG_MFD_CORE is not set
830# CONFIG_MFD_SM501 is not set
831# CONFIG_MFD_ASIC3 is not set
832# CONFIG_HTC_EGPIO is not set
833# CONFIG_HTC_PASIC3 is not set
834# CONFIG_TPS65010 is not set
835# CONFIG_TWL4030_CORE is not set
836# CONFIG_MFD_TMIO is not set
837# CONFIG_MFD_T7L66XB is not set
838# CONFIG_MFD_TC6387XB is not set
839# CONFIG_MFD_TC6393XB is not set
840# CONFIG_PMIC_DA903X is not set
841# CONFIG_MFD_WM8400 is not set
842# CONFIG_MFD_WM8350_I2C is not set
843# CONFIG_MFD_PCF50633 is not set
844# CONFIG_AB3100_CORE is not set
845# CONFIG_MEDIA_SUPPORT is not set
846
847#
848# Graphics support
849#
850# CONFIG_VGASTATE is not set
851# CONFIG_VIDEO_OUTPUT_CONTROL is not set
852# CONFIG_FB is not set
853# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
854
855#
856# Display device support
857#
858# CONFIG_DISPLAY_SUPPORT is not set
859
860#
861# Console display driver support
862#
863# CONFIG_VGA_CONSOLE is not set
864CONFIG_DUMMY_CONSOLE=y
865# CONFIG_SOUND is not set
866# CONFIG_HID_SUPPORT is not set
867CONFIG_USB_SUPPORT=y
868CONFIG_USB_ARCH_HAS_HCD=y
869CONFIG_USB_ARCH_HAS_OHCI=y
870# CONFIG_USB_ARCH_HAS_EHCI is not set
871CONFIG_USB=y
872# CONFIG_USB_DEBUG is not set
873# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
874
875#
876# Miscellaneous USB options
877#
878# CONFIG_USB_DEVICEFS is not set
879# CONFIG_USB_DEVICE_CLASS is not set
880# CONFIG_USB_DYNAMIC_MINORS is not set
881# CONFIG_USB_OTG is not set
882# CONFIG_USB_MON is not set
883# CONFIG_USB_WUSB is not set
884# CONFIG_USB_WUSB_CBAF is not set
885
886#
887# USB Host Controller Drivers
888#
889# CONFIG_USB_C67X00_HCD is not set
890# CONFIG_USB_OXU210HP_HCD is not set
891# CONFIG_USB_ISP116X_HCD is not set
892# CONFIG_USB_ISP1760_HCD is not set
893CONFIG_USB_OHCI_HCD=y
894# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
895# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
896CONFIG_USB_OHCI_LITTLE_ENDIAN=y
897# CONFIG_USB_SL811_HCD is not set
898# CONFIG_USB_R8A66597_HCD is not set
899# CONFIG_USB_HWA_HCD is not set
900# CONFIG_USB_MUSB_HDRC is not set
901# CONFIG_USB_GADGET_MUSB_HDRC is not set
902
903#
904# USB Device Class drivers
905#
906# CONFIG_USB_ACM is not set
907# CONFIG_USB_PRINTER is not set
908# CONFIG_USB_WDM is not set
909# CONFIG_USB_TMC is not set
910
911#
912# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
913#
914
915#
916# also be needed; see USB_STORAGE Help for more info
917#
918CONFIG_USB_STORAGE=y
919# CONFIG_USB_STORAGE_DEBUG is not set
920# CONFIG_USB_STORAGE_DATAFAB is not set
921# CONFIG_USB_STORAGE_FREECOM is not set
922# CONFIG_USB_STORAGE_ISD200 is not set
923# CONFIG_USB_STORAGE_USBAT is not set
924# CONFIG_USB_STORAGE_SDDR09 is not set
925# CONFIG_USB_STORAGE_SDDR55 is not set
926# CONFIG_USB_STORAGE_JUMPSHOT is not set
927# CONFIG_USB_STORAGE_ALAUDA is not set
928# CONFIG_USB_STORAGE_ONETOUCH is not set
929# CONFIG_USB_STORAGE_KARMA is not set
930# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
931# CONFIG_USB_LIBUSUAL is not set
932
933#
934# USB Imaging devices
935#
936# CONFIG_USB_MDC800 is not set
937# CONFIG_USB_MICROTEK is not set
938
939#
940# USB port drivers
941#
942# CONFIG_USB_SERIAL is not set
943
944#
945# USB Miscellaneous drivers
946#
947# CONFIG_USB_EMI62 is not set
948# CONFIG_USB_EMI26 is not set
949# CONFIG_USB_ADUTUX is not set
950# CONFIG_USB_SEVSEG is not set
951# CONFIG_USB_RIO500 is not set
952# CONFIG_USB_LEGOTOWER is not set
953# CONFIG_USB_LCD is not set
954# CONFIG_USB_BERRY_CHARGE is not set
955# CONFIG_USB_LED is not set
956# CONFIG_USB_CYPRESS_CY7C63 is not set
957# CONFIG_USB_CYTHERM is not set
958# CONFIG_USB_IDMOUSE is not set
959# CONFIG_USB_FTDI_ELAN is not set
960# CONFIG_USB_APPLEDISPLAY is not set
961# CONFIG_USB_LD is not set
962# CONFIG_USB_TRANCEVIBRATOR is not set
963# CONFIG_USB_IOWARRIOR is not set
964# CONFIG_USB_ISIGHTFW is not set
965# CONFIG_USB_VST is not set
966CONFIG_USB_GADGET=y
967# CONFIG_USB_GADGET_DEBUG_FILES is not set
968CONFIG_USB_GADGET_VBUS_DRAW=2
969CONFIG_USB_GADGET_SELECTED=y
970CONFIG_USB_GADGET_AT91=y
971CONFIG_USB_AT91=y
972# CONFIG_USB_GADGET_ATMEL_USBA is not set
973# CONFIG_USB_GADGET_FSL_USB2 is not set
974# CONFIG_USB_GADGET_LH7A40X is not set
975# CONFIG_USB_GADGET_OMAP is not set
976# CONFIG_USB_GADGET_PXA25X is not set
977# CONFIG_USB_GADGET_PXA27X is not set
978# CONFIG_USB_GADGET_S3C_HSOTG is not set
979# CONFIG_USB_GADGET_IMX is not set
980# CONFIG_USB_GADGET_S3C2410 is not set
981# CONFIG_USB_GADGET_M66592 is not set
982# CONFIG_USB_GADGET_AMD5536UDC is not set
983# CONFIG_USB_GADGET_FSL_QE is not set
984# CONFIG_USB_GADGET_CI13XXX is not set
985# CONFIG_USB_GADGET_NET2280 is not set
986# CONFIG_USB_GADGET_GOKU is not set
987# CONFIG_USB_GADGET_LANGWELL is not set
988# CONFIG_USB_GADGET_DUMMY_HCD is not set
989# CONFIG_USB_GADGET_DUALSPEED is not set
990# CONFIG_USB_ZERO is not set
991# CONFIG_USB_AUDIO is not set
992CONFIG_USB_ETH=y
993CONFIG_USB_ETH_RNDIS=y
994# CONFIG_USB_GADGETFS is not set
995# CONFIG_USB_FILE_STORAGE is not set
996# CONFIG_USB_G_SERIAL is not set
997# CONFIG_USB_MIDI_GADGET is not set
998# CONFIG_USB_G_PRINTER is not set
999# CONFIG_USB_CDC_COMPOSITE is not set
1000
1001#
1002# OTG and related infrastructure
1003#
1004# CONFIG_USB_GPIO_VBUS is not set
1005# CONFIG_NOP_USB_XCEIV is not set
1006CONFIG_MMC=y
1007# CONFIG_MMC_DEBUG is not set
1008# CONFIG_MMC_UNSAFE_RESUME is not set
1009
1010#
1011# MMC/SD/SDIO Card Drivers
1012#
1013CONFIG_MMC_BLOCK=y
1014CONFIG_MMC_BLOCK_BOUNCE=y
1015# CONFIG_SDIO_UART is not set
1016# CONFIG_MMC_TEST is not set
1017
1018#
1019# MMC/SD/SDIO Host Controller Drivers
1020#
1021# CONFIG_MMC_SDHCI is not set
1022CONFIG_MMC_AT91=y
1023# CONFIG_MEMSTICK is not set
1024# CONFIG_ACCESSIBILITY is not set
1025CONFIG_NEW_LEDS=y
1026CONFIG_LEDS_CLASS=y
1027
1028#
1029# LED drivers
1030#
1031# CONFIG_LEDS_PCA9532 is not set
1032CONFIG_LEDS_GPIO=y
1033CONFIG_LEDS_GPIO_PLATFORM=y
1034# CONFIG_LEDS_LP3944 is not set
1035# CONFIG_LEDS_PCA955X is not set
1036# CONFIG_LEDS_BD2802 is not set
1037
1038#
1039# LED Triggers
1040#
1041CONFIG_LEDS_TRIGGERS=y
1042CONFIG_LEDS_TRIGGER_TIMER=y
1043CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1044# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
1045CONFIG_LEDS_TRIGGER_GPIO=y
1046CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
1047
1048#
1049# iptables trigger is under Netfilter config (LED target)
1050#
1051CONFIG_RTC_LIB=y
1052CONFIG_RTC_CLASS=y
1053# CONFIG_RTC_HCTOSYS is not set
1054# CONFIG_RTC_DEBUG is not set
1055
1056#
1057# RTC interfaces
1058#
1059CONFIG_RTC_INTF_SYSFS=y
1060CONFIG_RTC_INTF_PROC=y
1061CONFIG_RTC_INTF_DEV=y
1062# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1063# CONFIG_RTC_DRV_TEST is not set
1064
1065#
1066# I2C RTC drivers
1067#
1068CONFIG_RTC_DRV_DS1307=y
1069# CONFIG_RTC_DRV_DS1374 is not set
1070# CONFIG_RTC_DRV_DS1672 is not set
1071# CONFIG_RTC_DRV_MAX6900 is not set
1072# CONFIG_RTC_DRV_RS5C372 is not set
1073# CONFIG_RTC_DRV_ISL1208 is not set
1074# CONFIG_RTC_DRV_X1205 is not set
1075# CONFIG_RTC_DRV_PCF8563 is not set
1076# CONFIG_RTC_DRV_PCF8583 is not set
1077# CONFIG_RTC_DRV_M41T80 is not set
1078# CONFIG_RTC_DRV_S35390A is not set
1079# CONFIG_RTC_DRV_FM3130 is not set
1080# CONFIG_RTC_DRV_RX8581 is not set
1081# CONFIG_RTC_DRV_RX8025 is not set
1082
1083#
1084# SPI RTC drivers
1085#
1086
1087#
1088# Platform RTC drivers
1089#
1090# CONFIG_RTC_DRV_CMOS is not set
1091# CONFIG_RTC_DRV_DS1286 is not set
1092# CONFIG_RTC_DRV_DS1511 is not set
1093# CONFIG_RTC_DRV_DS1553 is not set
1094# CONFIG_RTC_DRV_DS1742 is not set
1095# CONFIG_RTC_DRV_STK17TA8 is not set
1096# CONFIG_RTC_DRV_M48T86 is not set
1097# CONFIG_RTC_DRV_M48T35 is not set
1098# CONFIG_RTC_DRV_M48T59 is not set
1099# CONFIG_RTC_DRV_BQ4802 is not set
1100# CONFIG_RTC_DRV_V3020 is not set
1101
1102#
1103# on-CPU RTC drivers
1104#
1105# CONFIG_RTC_DRV_AT91SAM9 is not set
1106# CONFIG_DMADEVICES is not set
1107# CONFIG_AUXDISPLAY is not set
1108# CONFIG_REGULATOR is not set
1109# CONFIG_UIO is not set
1110# CONFIG_STAGING is not set
1111
1112#
1113# File systems
1114#
1115CONFIG_EXT2_FS=y
1116# CONFIG_EXT2_FS_XATTR is not set
1117# CONFIG_EXT2_FS_XIP is not set
1118CONFIG_EXT3_FS=y
1119# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
1120# CONFIG_EXT3_FS_XATTR is not set
1121# CONFIG_EXT4_FS is not set
1122CONFIG_JBD=y
1123# CONFIG_REISERFS_FS is not set
1124# CONFIG_JFS_FS is not set
1125# CONFIG_FS_POSIX_ACL is not set
1126# CONFIG_XFS_FS is not set
1127# CONFIG_GFS2_FS is not set
1128# CONFIG_OCFS2_FS is not set
1129# CONFIG_BTRFS_FS is not set
1130CONFIG_FILE_LOCKING=y
1131CONFIG_FSNOTIFY=y
1132CONFIG_DNOTIFY=y
1133CONFIG_INOTIFY=y
1134CONFIG_INOTIFY_USER=y
1135# CONFIG_QUOTA is not set
1136# CONFIG_AUTOFS_FS is not set
1137CONFIG_AUTOFS4_FS=y
1138# CONFIG_FUSE_FS is not set
1139
1140#
1141# Caches
1142#
1143# CONFIG_FSCACHE is not set
1144
1145#
1146# CD-ROM/DVD Filesystems
1147#
1148# CONFIG_ISO9660_FS is not set
1149# CONFIG_UDF_FS is not set
1150
1151#
1152# DOS/FAT/NT Filesystems
1153#
1154CONFIG_FAT_FS=y
1155CONFIG_MSDOS_FS=y
1156CONFIG_VFAT_FS=y
1157CONFIG_FAT_DEFAULT_CODEPAGE=437
1158CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1159# CONFIG_NTFS_FS is not set
1160
1161#
1162# Pseudo filesystems
1163#
1164CONFIG_PROC_FS=y
1165CONFIG_PROC_SYSCTL=y
1166CONFIG_PROC_PAGE_MONITOR=y
1167CONFIG_SYSFS=y
1168CONFIG_TMPFS=y
1169# CONFIG_TMPFS_POSIX_ACL is not set
1170# CONFIG_HUGETLB_PAGE is not set
1171# CONFIG_CONFIGFS_FS is not set
1172CONFIG_MISC_FILESYSTEMS=y
1173# CONFIG_ADFS_FS is not set
1174# CONFIG_AFFS_FS is not set
1175# CONFIG_HFS_FS is not set
1176# CONFIG_HFSPLUS_FS is not set
1177# CONFIG_BEFS_FS is not set
1178# CONFIG_BFS_FS is not set
1179# CONFIG_EFS_FS is not set
1180CONFIG_JFFS2_FS=y
1181CONFIG_JFFS2_FS_DEBUG=0
1182CONFIG_JFFS2_FS_WRITEBUFFER=y
1183# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1184CONFIG_JFFS2_SUMMARY=y
1185# CONFIG_JFFS2_FS_XATTR is not set
1186# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1187CONFIG_JFFS2_ZLIB=y
1188# CONFIG_JFFS2_LZO is not set
1189CONFIG_JFFS2_RTIME=y
1190# CONFIG_JFFS2_RUBIN is not set
1191CONFIG_CRAMFS=y
1192# CONFIG_SQUASHFS is not set
1193# CONFIG_VXFS_FS is not set
1194CONFIG_MINIX_FS=y
1195# CONFIG_OMFS_FS is not set
1196# CONFIG_HPFS_FS is not set
1197# CONFIG_QNX4FS_FS is not set
1198# CONFIG_ROMFS_FS is not set
1199# CONFIG_SYSV_FS is not set
1200# CONFIG_UFS_FS is not set
1201# CONFIG_NILFS2_FS is not set
1202CONFIG_NETWORK_FILESYSTEMS=y
1203CONFIG_NFS_FS=y
1204CONFIG_NFS_V3=y
1205# CONFIG_NFS_V3_ACL is not set
1206# CONFIG_NFS_V4 is not set
1207CONFIG_ROOT_NFS=y
1208# CONFIG_NFSD is not set
1209CONFIG_LOCKD=y
1210CONFIG_LOCKD_V4=y
1211CONFIG_NFS_COMMON=y
1212CONFIG_SUNRPC=y
1213# CONFIG_RPCSEC_GSS_KRB5 is not set
1214# CONFIG_RPCSEC_GSS_SPKM3 is not set
1215# CONFIG_SMB_FS is not set
1216# CONFIG_CIFS is not set
1217# CONFIG_NCP_FS is not set
1218# CONFIG_CODA_FS is not set
1219# CONFIG_AFS_FS is not set
1220
1221#
1222# Partition Types
1223#
1224CONFIG_PARTITION_ADVANCED=y
1225# CONFIG_ACORN_PARTITION is not set
1226# CONFIG_OSF_PARTITION is not set
1227# CONFIG_AMIGA_PARTITION is not set
1228# CONFIG_ATARI_PARTITION is not set
1229# CONFIG_MAC_PARTITION is not set
1230CONFIG_MSDOS_PARTITION=y
1231# CONFIG_BSD_DISKLABEL is not set
1232# CONFIG_MINIX_SUBPARTITION is not set
1233# CONFIG_SOLARIS_X86_PARTITION is not set
1234# CONFIG_UNIXWARE_DISKLABEL is not set
1235# CONFIG_LDM_PARTITION is not set
1236# CONFIG_SGI_PARTITION is not set
1237# CONFIG_ULTRIX_PARTITION is not set
1238# CONFIG_SUN_PARTITION is not set
1239# CONFIG_KARMA_PARTITION is not set
1240# CONFIG_EFI_PARTITION is not set
1241# CONFIG_SYSV68_PARTITION is not set
1242CONFIG_NLS=y
1243CONFIG_NLS_DEFAULT="iso8859-1"
1244CONFIG_NLS_CODEPAGE_437=y
1245# CONFIG_NLS_CODEPAGE_737 is not set
1246# CONFIG_NLS_CODEPAGE_775 is not set
1247# CONFIG_NLS_CODEPAGE_850 is not set
1248# CONFIG_NLS_CODEPAGE_852 is not set
1249# CONFIG_NLS_CODEPAGE_855 is not set
1250# CONFIG_NLS_CODEPAGE_857 is not set
1251# CONFIG_NLS_CODEPAGE_860 is not set
1252# CONFIG_NLS_CODEPAGE_861 is not set
1253# CONFIG_NLS_CODEPAGE_862 is not set
1254# CONFIG_NLS_CODEPAGE_863 is not set
1255# CONFIG_NLS_CODEPAGE_864 is not set
1256# CONFIG_NLS_CODEPAGE_865 is not set
1257# CONFIG_NLS_CODEPAGE_866 is not set
1258# CONFIG_NLS_CODEPAGE_869 is not set
1259# CONFIG_NLS_CODEPAGE_936 is not set
1260# CONFIG_NLS_CODEPAGE_950 is not set
1261# CONFIG_NLS_CODEPAGE_932 is not set
1262# CONFIG_NLS_CODEPAGE_949 is not set
1263# CONFIG_NLS_CODEPAGE_874 is not set
1264# CONFIG_NLS_ISO8859_8 is not set
1265# CONFIG_NLS_CODEPAGE_1250 is not set
1266# CONFIG_NLS_CODEPAGE_1251 is not set
1267# CONFIG_NLS_ASCII is not set
1268CONFIG_NLS_ISO8859_1=y
1269# CONFIG_NLS_ISO8859_2 is not set
1270# CONFIG_NLS_ISO8859_3 is not set
1271# CONFIG_NLS_ISO8859_4 is not set
1272# CONFIG_NLS_ISO8859_5 is not set
1273# CONFIG_NLS_ISO8859_6 is not set
1274# CONFIG_NLS_ISO8859_7 is not set
1275# CONFIG_NLS_ISO8859_9 is not set
1276# CONFIG_NLS_ISO8859_13 is not set
1277# CONFIG_NLS_ISO8859_14 is not set
1278# CONFIG_NLS_ISO8859_15 is not set
1279# CONFIG_NLS_KOI8_R is not set
1280# CONFIG_NLS_KOI8_U is not set
1281CONFIG_NLS_UTF8=y
1282# CONFIG_DLM is not set
1283
1284#
1285# Kernel hacking
1286#
1287# CONFIG_PRINTK_TIME is not set
1288CONFIG_ENABLE_WARN_DEPRECATED=y
1289CONFIG_ENABLE_MUST_CHECK=y
1290CONFIG_FRAME_WARN=1024
1291# CONFIG_MAGIC_SYSRQ is not set
1292# CONFIG_UNUSED_SYMBOLS is not set
1293# CONFIG_DEBUG_FS is not set
1294# CONFIG_HEADERS_CHECK is not set
1295# CONFIG_DEBUG_KERNEL is not set
1296# CONFIG_SLUB_DEBUG_ON is not set
1297# CONFIG_SLUB_STATS is not set
1298CONFIG_DEBUG_BUGVERBOSE=y
1299CONFIG_DEBUG_MEMORY_INIT=y
1300# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1301# CONFIG_LATENCYTOP is not set
1302# CONFIG_SYSCTL_SYSCALL_CHECK is not set
1303CONFIG_HAVE_FUNCTION_TRACER=y
1304CONFIG_TRACING_SUPPORT=y
1305# CONFIG_FTRACE is not set
1306# CONFIG_SAMPLES is not set
1307CONFIG_HAVE_ARCH_KGDB=y
1308CONFIG_ARM_UNWIND=y
1309# CONFIG_DEBUG_USER is not set
1310
1311#
1312# Security options
1313#
1314# CONFIG_KEYS is not set
1315# CONFIG_SECURITY is not set
1316# CONFIG_SECURITYFS is not set
1317# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1318# CONFIG_CRYPTO is not set
1319# CONFIG_BINARY_PRINTF is not set
1320
1321#
1322# Library routines
1323#
1324CONFIG_BITREVERSE=y
1325CONFIG_GENERIC_FIND_LAST_BIT=y
1326CONFIG_CRC_CCITT=y
1327# CONFIG_CRC16 is not set
1328# CONFIG_CRC_T10DIF is not set
1329# CONFIG_CRC_ITU_T is not set
1330CONFIG_CRC32=y
1331# CONFIG_CRC7 is not set
1332# CONFIG_LIBCRC32C is not set
1333CONFIG_ZLIB_INFLATE=y
1334CONFIG_ZLIB_DEFLATE=y
1335CONFIG_HAS_IOMEM=y
1336CONFIG_HAS_IOPORT=y
1337CONFIG_HAS_DMA=y
1338CONFIG_NLATTR=y
diff --git a/arch/arm/configs/cpu9g20_defconfig b/arch/arm/configs/cpu9g20_defconfig
new file mode 100644
index 000000000000..b5b9cbbc6977
--- /dev/null
+++ b/arch/arm/configs/cpu9g20_defconfig
@@ -0,0 +1,1328 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.31-rc3
4# Tue Jul 14 15:03:43 2009
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12CONFIG_GENERIC_HARDIRQS=y
13CONFIG_STACKTRACE_SUPPORT=y
14CONFIG_HAVE_LATENCYTOP_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20CONFIG_GENERIC_HWEIGHT=y
21CONFIG_GENERIC_CALIBRATE_DELAY=y
22CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
23CONFIG_VECTORS_BASE=0xffff0000
24CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
25CONFIG_CONSTRUCTORS=y
26
27#
28# General setup
29#
30CONFIG_EXPERIMENTAL=y
31CONFIG_BROKEN_ON_SMP=y
32CONFIG_LOCK_KERNEL=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36# CONFIG_SWAP is not set
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39# CONFIG_POSIX_MQUEUE is not set
40# CONFIG_BSD_PROCESS_ACCT is not set
41# CONFIG_TASKSTATS is not set
42# CONFIG_AUDIT is not set
43
44#
45# RCU Subsystem
46#
47CONFIG_CLASSIC_RCU=y
48# CONFIG_TREE_RCU is not set
49# CONFIG_PREEMPT_RCU is not set
50# CONFIG_TREE_RCU_TRACE is not set
51# CONFIG_PREEMPT_RCU_TRACE is not set
52# CONFIG_IKCONFIG is not set
53CONFIG_LOG_BUF_SHIFT=14
54# CONFIG_GROUP_SCHED is not set
55# CONFIG_CGROUPS is not set
56CONFIG_SYSFS_DEPRECATED=y
57CONFIG_SYSFS_DEPRECATED_V2=y
58# CONFIG_RELAY is not set
59CONFIG_NAMESPACES=y
60# CONFIG_UTS_NS is not set
61# CONFIG_IPC_NS is not set
62# CONFIG_USER_NS is not set
63# CONFIG_PID_NS is not set
64# CONFIG_NET_NS is not set
65# CONFIG_BLK_DEV_INITRD is not set
66CONFIG_CC_OPTIMIZE_FOR_SIZE=y
67CONFIG_SYSCTL=y
68CONFIG_ANON_INODES=y
69# CONFIG_EMBEDDED is not set
70CONFIG_UID16=y
71CONFIG_SYSCTL_SYSCALL=y
72CONFIG_KALLSYMS=y
73# CONFIG_KALLSYMS_EXTRA_PASS is not set
74CONFIG_HOTPLUG=y
75CONFIG_PRINTK=y
76CONFIG_BUG=y
77CONFIG_ELF_CORE=y
78CONFIG_BASE_FULL=y
79CONFIG_FUTEX=y
80CONFIG_EPOLL=y
81CONFIG_SIGNALFD=y
82CONFIG_TIMERFD=y
83CONFIG_EVENTFD=y
84CONFIG_SHMEM=y
85CONFIG_AIO=y
86
87#
88# Performance Counters
89#
90CONFIG_VM_EVENT_COUNTERS=y
91CONFIG_SLUB_DEBUG=y
92# CONFIG_STRIP_ASM_SYMS is not set
93CONFIG_COMPAT_BRK=y
94# CONFIG_SLAB is not set
95CONFIG_SLUB=y
96# CONFIG_SLOB is not set
97# CONFIG_PROFILING is not set
98# CONFIG_MARKERS is not set
99CONFIG_HAVE_OPROFILE=y
100# CONFIG_KPROBES is not set
101CONFIG_HAVE_KPROBES=y
102CONFIG_HAVE_KRETPROBES=y
103CONFIG_HAVE_CLK=y
104
105#
106# GCOV-based kernel profiling
107#
108# CONFIG_SLOW_WORK is not set
109CONFIG_HAVE_GENERIC_DMA_COHERENT=y
110CONFIG_SLABINFO=y
111CONFIG_RT_MUTEXES=y
112CONFIG_BASE_SMALL=0
113CONFIG_MODULES=y
114# CONFIG_MODULE_FORCE_LOAD is not set
115CONFIG_MODULE_UNLOAD=y
116# CONFIG_MODULE_FORCE_UNLOAD is not set
117# CONFIG_MODVERSIONS is not set
118# CONFIG_MODULE_SRCVERSION_ALL is not set
119CONFIG_BLOCK=y
120CONFIG_LBDAF=y
121# CONFIG_BLK_DEV_BSG is not set
122# CONFIG_BLK_DEV_INTEGRITY is not set
123
124#
125# IO Schedulers
126#
127CONFIG_IOSCHED_NOOP=y
128# CONFIG_IOSCHED_AS is not set
129CONFIG_IOSCHED_DEADLINE=y
130# CONFIG_IOSCHED_CFQ is not set
131# CONFIG_DEFAULT_AS is not set
132CONFIG_DEFAULT_DEADLINE=y
133# CONFIG_DEFAULT_CFQ is not set
134# CONFIG_DEFAULT_NOOP is not set
135CONFIG_DEFAULT_IOSCHED="deadline"
136# CONFIG_FREEZER is not set
137
138#
139# System Type
140#
141# CONFIG_ARCH_AAEC2000 is not set
142# CONFIG_ARCH_INTEGRATOR is not set
143# CONFIG_ARCH_REALVIEW is not set
144# CONFIG_ARCH_VERSATILE is not set
145CONFIG_ARCH_AT91=y
146# CONFIG_ARCH_CLPS711X is not set
147# CONFIG_ARCH_GEMINI is not set
148# CONFIG_ARCH_EBSA110 is not set
149# CONFIG_ARCH_EP93XX is not set
150# CONFIG_ARCH_FOOTBRIDGE is not set
151# CONFIG_ARCH_MXC is not set
152# CONFIG_ARCH_STMP3XXX is not set
153# CONFIG_ARCH_NETX is not set
154# CONFIG_ARCH_H720X is not set
155# CONFIG_ARCH_IOP13XX is not set
156# CONFIG_ARCH_IOP32X is not set
157# CONFIG_ARCH_IOP33X is not set
158# CONFIG_ARCH_IXP23XX is not set
159# CONFIG_ARCH_IXP2000 is not set
160# CONFIG_ARCH_IXP4XX is not set
161# CONFIG_ARCH_L7200 is not set
162# CONFIG_ARCH_KIRKWOOD is not set
163# CONFIG_ARCH_LOKI is not set
164# CONFIG_ARCH_MV78XX0 is not set
165# CONFIG_ARCH_ORION5X is not set
166# CONFIG_ARCH_MMP is not set
167# CONFIG_ARCH_KS8695 is not set
168# CONFIG_ARCH_NS9XXX is not set
169# CONFIG_ARCH_W90X900 is not set
170# CONFIG_ARCH_PNX4008 is not set
171# CONFIG_ARCH_PXA is not set
172# CONFIG_ARCH_MSM is not set
173# CONFIG_ARCH_RPC is not set
174# CONFIG_ARCH_SA1100 is not set
175# CONFIG_ARCH_S3C2410 is not set
176# CONFIG_ARCH_S3C64XX is not set
177# CONFIG_ARCH_SHARK is not set
178# CONFIG_ARCH_LH7A40X is not set
179# CONFIG_ARCH_U300 is not set
180# CONFIG_ARCH_DAVINCI is not set
181# CONFIG_ARCH_OMAP is not set
182
183#
184# Atmel AT91 System-on-Chip
185#
186# CONFIG_ARCH_AT91RM9200 is not set
187# CONFIG_ARCH_AT91SAM9260 is not set
188# CONFIG_ARCH_AT91SAM9261 is not set
189# CONFIG_ARCH_AT91SAM9263 is not set
190# CONFIG_ARCH_AT91SAM9RL is not set
191CONFIG_ARCH_AT91SAM9G20=y
192# CONFIG_ARCH_AT91CAP9 is not set
193# CONFIG_ARCH_AT91X40 is not set
194CONFIG_AT91_PMC_UNIT=y
195
196#
197# AT91SAM9G20 Board Type
198#
199# CONFIG_MACH_AT91SAM9G20EK is not set
200CONFIG_MACH_CPU9G20=y
201
202#
203# AT91 Board Options
204#
205
206#
207# AT91 Feature Selections
208#
209# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
210CONFIG_AT91_TIMER_HZ=100
211CONFIG_AT91_EARLY_DBGU=y
212# CONFIG_AT91_EARLY_USART0 is not set
213# CONFIG_AT91_EARLY_USART1 is not set
214# CONFIG_AT91_EARLY_USART2 is not set
215# CONFIG_AT91_EARLY_USART3 is not set
216# CONFIG_AT91_EARLY_USART4 is not set
217# CONFIG_AT91_EARLY_USART5 is not set
218
219#
220# Processor Type
221#
222CONFIG_CPU_32=y
223CONFIG_CPU_ARM926T=y
224CONFIG_CPU_32v5=y
225CONFIG_CPU_ABRT_EV5TJ=y
226CONFIG_CPU_PABRT_NOIFAR=y
227CONFIG_CPU_CACHE_VIVT=y
228CONFIG_CPU_COPY_V4WB=y
229CONFIG_CPU_TLB_V4WBI=y
230CONFIG_CPU_CP15=y
231CONFIG_CPU_CP15_MMU=y
232
233#
234# Processor Features
235#
236# CONFIG_ARM_THUMB is not set
237# CONFIG_CPU_ICACHE_DISABLE is not set
238# CONFIG_CPU_DCACHE_DISABLE is not set
239# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
240# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
241
242#
243# Bus support
244#
245# CONFIG_PCI_SYSCALL is not set
246# CONFIG_ARCH_SUPPORTS_MSI is not set
247# CONFIG_PCCARD is not set
248
249#
250# Kernel Features
251#
252# CONFIG_NO_HZ is not set
253# CONFIG_HIGH_RES_TIMERS is not set
254CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
255CONFIG_VMSPLIT_3G=y
256# CONFIG_VMSPLIT_2G is not set
257# CONFIG_VMSPLIT_1G is not set
258CONFIG_PAGE_OFFSET=0xC0000000
259CONFIG_PREEMPT=y
260CONFIG_HZ=100
261CONFIG_AEABI=y
262CONFIG_OABI_COMPAT=y
263# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
264# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
265# CONFIG_HIGHMEM is not set
266CONFIG_SELECT_MEMORY_MODEL=y
267CONFIG_FLATMEM_MANUAL=y
268# CONFIG_DISCONTIGMEM_MANUAL is not set
269# CONFIG_SPARSEMEM_MANUAL is not set
270CONFIG_FLATMEM=y
271CONFIG_FLAT_NODE_MEM_MAP=y
272CONFIG_PAGEFLAGS_EXTENDED=y
273CONFIG_SPLIT_PTLOCK_CPUS=4096
274# CONFIG_PHYS_ADDR_T_64BIT is not set
275CONFIG_ZONE_DMA_FLAG=0
276CONFIG_VIRT_TO_BUS=y
277CONFIG_HAVE_MLOCK=y
278CONFIG_HAVE_MLOCKED_PAGE_BIT=y
279CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
280# CONFIG_LEDS is not set
281CONFIG_ALIGNMENT_TRAP=y
282# CONFIG_UACCESS_WITH_MEMCPY is not set
283
284#
285# Boot options
286#
287CONFIG_ZBOOT_ROM_TEXT=0x0
288CONFIG_ZBOOT_ROM_BSS=0x0
289CONFIG_CMDLINE=""
290# CONFIG_XIP_KERNEL is not set
291# CONFIG_KEXEC is not set
292
293#
294# CPU Power Management
295#
296# CONFIG_CPU_IDLE is not set
297
298#
299# Floating point emulation
300#
301
302#
303# At least one emulation must be selected
304#
305# CONFIG_FPE_NWFPE is not set
306# CONFIG_FPE_FASTFPE is not set
307# CONFIG_VFP is not set
308
309#
310# Userspace binary formats
311#
312CONFIG_BINFMT_ELF=y
313# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
314CONFIG_HAVE_AOUT=y
315# CONFIG_BINFMT_AOUT is not set
316# CONFIG_BINFMT_MISC is not set
317
318#
319# Power management options
320#
321# CONFIG_PM is not set
322CONFIG_ARCH_SUSPEND_POSSIBLE=y
323CONFIG_NET=y
324
325#
326# Networking options
327#
328CONFIG_PACKET=y
329# CONFIG_PACKET_MMAP is not set
330CONFIG_UNIX=y
331# CONFIG_NET_KEY is not set
332CONFIG_INET=y
333# CONFIG_IP_MULTICAST is not set
334# CONFIG_IP_ADVANCED_ROUTER is not set
335CONFIG_IP_FIB_HASH=y
336CONFIG_IP_PNP=y
337# CONFIG_IP_PNP_DHCP is not set
338# CONFIG_IP_PNP_BOOTP is not set
339# CONFIG_IP_PNP_RARP is not set
340# CONFIG_NET_IPIP is not set
341# CONFIG_NET_IPGRE is not set
342# CONFIG_ARPD is not set
343# CONFIG_SYN_COOKIES is not set
344# CONFIG_INET_AH is not set
345# CONFIG_INET_ESP is not set
346# CONFIG_INET_IPCOMP is not set
347# CONFIG_INET_XFRM_TUNNEL is not set
348# CONFIG_INET_TUNNEL is not set
349# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
350# CONFIG_INET_XFRM_MODE_TUNNEL is not set
351# CONFIG_INET_XFRM_MODE_BEET is not set
352CONFIG_INET_LRO=y
353CONFIG_INET_DIAG=y
354CONFIG_INET_TCP_DIAG=y
355# CONFIG_TCP_CONG_ADVANCED is not set
356CONFIG_TCP_CONG_CUBIC=y
357CONFIG_DEFAULT_TCP_CONG="cubic"
358# CONFIG_TCP_MD5SIG is not set
359# CONFIG_IPV6 is not set
360# CONFIG_NETWORK_SECMARK is not set
361# CONFIG_NETFILTER is not set
362# CONFIG_IP_DCCP is not set
363# CONFIG_IP_SCTP is not set
364# CONFIG_TIPC is not set
365# CONFIG_ATM is not set
366# CONFIG_BRIDGE is not set
367# CONFIG_NET_DSA is not set
368# CONFIG_VLAN_8021Q is not set
369# CONFIG_DECNET is not set
370# CONFIG_LLC2 is not set
371# CONFIG_IPX is not set
372# CONFIG_ATALK is not set
373# CONFIG_X25 is not set
374# CONFIG_LAPB is not set
375# CONFIG_ECONET is not set
376# CONFIG_WAN_ROUTER is not set
377# CONFIG_PHONET is not set
378# CONFIG_IEEE802154 is not set
379# CONFIG_NET_SCHED is not set
380# CONFIG_DCB is not set
381
382#
383# Network testing
384#
385# CONFIG_NET_PKTGEN is not set
386# CONFIG_HAMRADIO is not set
387# CONFIG_CAN is not set
388# CONFIG_IRDA is not set
389# CONFIG_BT is not set
390# CONFIG_AF_RXRPC is not set
391# CONFIG_WIRELESS is not set
392# CONFIG_WIMAX is not set
393# CONFIG_RFKILL is not set
394# CONFIG_NET_9P is not set
395
396#
397# Device Drivers
398#
399
400#
401# Generic Driver Options
402#
403CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
404CONFIG_STANDALONE=y
405CONFIG_PREVENT_FIRMWARE_BUILD=y
406CONFIG_FW_LOADER=y
407CONFIG_FIRMWARE_IN_KERNEL=y
408CONFIG_EXTRA_FIRMWARE=""
409# CONFIG_SYS_HYPERVISOR is not set
410# CONFIG_CONNECTOR is not set
411CONFIG_MTD=y
412# CONFIG_MTD_DEBUG is not set
413# CONFIG_MTD_CONCAT is not set
414CONFIG_MTD_PARTITIONS=y
415# CONFIG_MTD_TESTS is not set
416# CONFIG_MTD_REDBOOT_PARTS is not set
417CONFIG_MTD_CMDLINE_PARTS=y
418# CONFIG_MTD_AFS_PARTS is not set
419# CONFIG_MTD_AR7_PARTS is not set
420
421#
422# User Modules And Translation Layers
423#
424CONFIG_MTD_CHAR=y
425CONFIG_MTD_BLKDEVS=y
426CONFIG_MTD_BLOCK=y
427# CONFIG_FTL is not set
428# CONFIG_NFTL is not set
429# CONFIG_INFTL is not set
430# CONFIG_RFD_FTL is not set
431# CONFIG_SSFDC is not set
432# CONFIG_MTD_OOPS is not set
433
434#
435# RAM/ROM/Flash chip drivers
436#
437CONFIG_MTD_CFI=y
438# CONFIG_MTD_JEDECPROBE is not set
439CONFIG_MTD_GEN_PROBE=y
440# CONFIG_MTD_CFI_ADV_OPTIONS is not set
441CONFIG_MTD_MAP_BANK_WIDTH_1=y
442CONFIG_MTD_MAP_BANK_WIDTH_2=y
443CONFIG_MTD_MAP_BANK_WIDTH_4=y
444# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
445# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
446# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
447CONFIG_MTD_CFI_I1=y
448CONFIG_MTD_CFI_I2=y
449# CONFIG_MTD_CFI_I4 is not set
450# CONFIG_MTD_CFI_I8 is not set
451CONFIG_MTD_CFI_INTELEXT=y
452# CONFIG_MTD_CFI_AMDSTD is not set
453# CONFIG_MTD_CFI_STAA is not set
454CONFIG_MTD_CFI_UTIL=y
455CONFIG_MTD_RAM=y
456# CONFIG_MTD_ROM is not set
457# CONFIG_MTD_ABSENT is not set
458
459#
460# Mapping drivers for chip access
461#
462# CONFIG_MTD_COMPLEX_MAPPINGS is not set
463CONFIG_MTD_PHYSMAP=y
464# CONFIG_MTD_PHYSMAP_COMPAT is not set
465# CONFIG_MTD_ARM_INTEGRATOR is not set
466CONFIG_MTD_PLATRAM=y
467
468#
469# Self-contained MTD device drivers
470#
471# CONFIG_MTD_SLRAM is not set
472# CONFIG_MTD_PHRAM is not set
473# CONFIG_MTD_MTDRAM is not set
474# CONFIG_MTD_BLOCK2MTD is not set
475
476#
477# Disk-On-Chip Device Drivers
478#
479# CONFIG_MTD_DOC2000 is not set
480# CONFIG_MTD_DOC2001 is not set
481# CONFIG_MTD_DOC2001PLUS is not set
482CONFIG_MTD_NAND=y
483# CONFIG_MTD_NAND_VERIFY_WRITE is not set
484# CONFIG_MTD_NAND_ECC_SMC is not set
485# CONFIG_MTD_NAND_MUSEUM_IDS is not set
486# CONFIG_MTD_NAND_GPIO is not set
487CONFIG_MTD_NAND_IDS=y
488# CONFIG_MTD_NAND_DISKONCHIP is not set
489CONFIG_MTD_NAND_ATMEL=y
490# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
491CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
492# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
493# CONFIG_MTD_NAND_NANDSIM is not set
494# CONFIG_MTD_NAND_PLATFORM is not set
495# CONFIG_MTD_ALAUDA is not set
496# CONFIG_MTD_ONENAND is not set
497
498#
499# LPDDR flash memory drivers
500#
501# CONFIG_MTD_LPDDR is not set
502
503#
504# UBI - Unsorted block images
505#
506# CONFIG_MTD_UBI is not set
507# CONFIG_PARPORT is not set
508CONFIG_BLK_DEV=y
509# CONFIG_BLK_DEV_COW_COMMON is not set
510CONFIG_BLK_DEV_LOOP=y
511# CONFIG_BLK_DEV_CRYPTOLOOP is not set
512CONFIG_BLK_DEV_NBD=y
513# CONFIG_BLK_DEV_UB is not set
514CONFIG_BLK_DEV_RAM=y
515CONFIG_BLK_DEV_RAM_COUNT=16
516CONFIG_BLK_DEV_RAM_SIZE=4096
517# CONFIG_BLK_DEV_XIP is not set
518# CONFIG_CDROM_PKTCDVD is not set
519# CONFIG_ATA_OVER_ETH is not set
520# CONFIG_MG_DISK is not set
521# CONFIG_MISC_DEVICES is not set
522CONFIG_HAVE_IDE=y
523# CONFIG_IDE is not set
524
525#
526# SCSI device support
527#
528# CONFIG_RAID_ATTRS is not set
529CONFIG_SCSI=y
530CONFIG_SCSI_DMA=y
531# CONFIG_SCSI_TGT is not set
532# CONFIG_SCSI_NETLINK is not set
533CONFIG_SCSI_PROC_FS=y
534
535#
536# SCSI support type (disk, tape, CD-ROM)
537#
538CONFIG_BLK_DEV_SD=y
539# CONFIG_CHR_DEV_ST is not set
540# CONFIG_CHR_DEV_OSST is not set
541# CONFIG_BLK_DEV_SR is not set
542# CONFIG_CHR_DEV_SG is not set
543# CONFIG_CHR_DEV_SCH is not set
544CONFIG_SCSI_MULTI_LUN=y
545# CONFIG_SCSI_CONSTANTS is not set
546# CONFIG_SCSI_LOGGING is not set
547# CONFIG_SCSI_SCAN_ASYNC is not set
548CONFIG_SCSI_WAIT_SCAN=m
549
550#
551# SCSI Transports
552#
553# CONFIG_SCSI_SPI_ATTRS is not set
554# CONFIG_SCSI_FC_ATTRS is not set
555# CONFIG_SCSI_ISCSI_ATTRS is not set
556# CONFIG_SCSI_SAS_LIBSAS is not set
557# CONFIG_SCSI_SRP_ATTRS is not set
558# CONFIG_SCSI_LOWLEVEL is not set
559# CONFIG_SCSI_DH is not set
560# CONFIG_SCSI_OSD_INITIATOR is not set
561# CONFIG_ATA is not set
562# CONFIG_MD is not set
563CONFIG_NETDEVICES=y
564# CONFIG_DUMMY is not set
565# CONFIG_BONDING is not set
566# CONFIG_MACVLAN is not set
567# CONFIG_EQUALIZER is not set
568# CONFIG_TUN is not set
569# CONFIG_VETH is not set
570CONFIG_PHYLIB=y
571
572#
573# MII PHY device drivers
574#
575# CONFIG_MARVELL_PHY is not set
576# CONFIG_DAVICOM_PHY is not set
577# CONFIG_QSEMI_PHY is not set
578# CONFIG_LXT_PHY is not set
579# CONFIG_CICADA_PHY is not set
580# CONFIG_VITESSE_PHY is not set
581CONFIG_SMSC_PHY=y
582# CONFIG_BROADCOM_PHY is not set
583# CONFIG_ICPLUS_PHY is not set
584# CONFIG_REALTEK_PHY is not set
585# CONFIG_NATIONAL_PHY is not set
586# CONFIG_STE10XP is not set
587# CONFIG_LSI_ET1011C_PHY is not set
588# CONFIG_FIXED_PHY is not set
589# CONFIG_MDIO_BITBANG is not set
590CONFIG_NET_ETHERNET=y
591CONFIG_MII=y
592CONFIG_MACB=y
593# CONFIG_AX88796 is not set
594# CONFIG_SMC91X is not set
595# CONFIG_DM9000 is not set
596# CONFIG_ETHOC is not set
597# CONFIG_SMC911X is not set
598# CONFIG_SMSC911X is not set
599# CONFIG_DNET is not set
600# CONFIG_IBM_NEW_EMAC_ZMII is not set
601# CONFIG_IBM_NEW_EMAC_RGMII is not set
602# CONFIG_IBM_NEW_EMAC_TAH is not set
603# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
604# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
605# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
606# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
607# CONFIG_B44 is not set
608# CONFIG_KS8842 is not set
609# CONFIG_NETDEV_1000 is not set
610# CONFIG_NETDEV_10000 is not set
611
612#
613# Wireless LAN
614#
615# CONFIG_WLAN_PRE80211 is not set
616# CONFIG_WLAN_80211 is not set
617
618#
619# Enable WiMAX (Networking options) to see the WiMAX drivers
620#
621
622#
623# USB Network Adapters
624#
625# CONFIG_USB_CATC is not set
626# CONFIG_USB_KAWETH is not set
627# CONFIG_USB_PEGASUS is not set
628# CONFIG_USB_RTL8150 is not set
629# CONFIG_USB_USBNET is not set
630# CONFIG_WAN is not set
631CONFIG_PPP=y
632# CONFIG_PPP_MULTILINK is not set
633# CONFIG_PPP_FILTER is not set
634CONFIG_PPP_ASYNC=y
635# CONFIG_PPP_SYNC_TTY is not set
636CONFIG_PPP_DEFLATE=y
637CONFIG_PPP_BSDCOMP=y
638# CONFIG_PPP_MPPE is not set
639# CONFIG_PPPOE is not set
640# CONFIG_PPPOL2TP is not set
641# CONFIG_SLIP is not set
642CONFIG_SLHC=y
643# CONFIG_NETCONSOLE is not set
644# CONFIG_NETPOLL is not set
645# CONFIG_NET_POLL_CONTROLLER is not set
646# CONFIG_ISDN is not set
647
648#
649# Input device support
650#
651CONFIG_INPUT=y
652# CONFIG_INPUT_FF_MEMLESS is not set
653# CONFIG_INPUT_POLLDEV is not set
654
655#
656# Userland interfaces
657#
658CONFIG_INPUT_MOUSEDEV=y
659# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
660CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
661CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
662# CONFIG_INPUT_JOYDEV is not set
663# CONFIG_INPUT_EVDEV is not set
664# CONFIG_INPUT_EVBUG is not set
665
666#
667# Input Device Drivers
668#
669CONFIG_INPUT_KEYBOARD=y
670# CONFIG_KEYBOARD_ATKBD is not set
671# CONFIG_KEYBOARD_LKKBD is not set
672CONFIG_KEYBOARD_GPIO=y
673# CONFIG_KEYBOARD_MATRIX is not set
674# CONFIG_KEYBOARD_LM8323 is not set
675# CONFIG_KEYBOARD_NEWTON is not set
676# CONFIG_KEYBOARD_STOWAWAY is not set
677# CONFIG_KEYBOARD_SUNKBD is not set
678# CONFIG_KEYBOARD_XTKBD is not set
679# CONFIG_INPUT_MOUSE is not set
680# CONFIG_INPUT_JOYSTICK is not set
681# CONFIG_INPUT_TABLET is not set
682# CONFIG_INPUT_TOUCHSCREEN is not set
683# CONFIG_INPUT_MISC is not set
684
685#
686# Hardware I/O ports
687#
688# CONFIG_SERIO is not set
689# CONFIG_GAMEPORT is not set
690
691#
692# Character devices
693#
694CONFIG_VT=y
695CONFIG_CONSOLE_TRANSLATIONS=y
696CONFIG_VT_CONSOLE=y
697CONFIG_HW_CONSOLE=y
698# CONFIG_VT_HW_CONSOLE_BINDING is not set
699CONFIG_DEVKMEM=y
700# CONFIG_SERIAL_NONSTANDARD is not set
701
702#
703# Serial drivers
704#
705# CONFIG_SERIAL_8250 is not set
706
707#
708# Non-8250 serial port support
709#
710CONFIG_SERIAL_ATMEL=y
711CONFIG_SERIAL_ATMEL_CONSOLE=y
712CONFIG_SERIAL_ATMEL_PDC=y
713# CONFIG_SERIAL_ATMEL_TTYAT is not set
714CONFIG_SERIAL_CORE=y
715CONFIG_SERIAL_CORE_CONSOLE=y
716CONFIG_UNIX98_PTYS=y
717# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
718CONFIG_LEGACY_PTYS=y
719CONFIG_LEGACY_PTY_COUNT=32
720# CONFIG_IPMI_HANDLER is not set
721# CONFIG_HW_RANDOM is not set
722# CONFIG_R3964 is not set
723# CONFIG_RAW_DRIVER is not set
724# CONFIG_TCG_TPM is not set
725CONFIG_I2C=y
726CONFIG_I2C_BOARDINFO=y
727CONFIG_I2C_CHARDEV=y
728CONFIG_I2C_HELPER_AUTO=y
729CONFIG_I2C_ALGOBIT=y
730
731#
732# I2C Hardware Bus support
733#
734
735#
736# I2C system bus drivers (mostly embedded / system-on-chip)
737#
738# CONFIG_I2C_DESIGNWARE is not set
739CONFIG_I2C_GPIO=y
740# CONFIG_I2C_OCORES is not set
741# CONFIG_I2C_SIMTEC is not set
742
743#
744# External I2C/SMBus adapter drivers
745#
746# CONFIG_I2C_PARPORT_LIGHT is not set
747# CONFIG_I2C_TAOS_EVM is not set
748# CONFIG_I2C_TINY_USB is not set
749
750#
751# Other I2C/SMBus bus drivers
752#
753# CONFIG_I2C_PCA_PLATFORM is not set
754# CONFIG_I2C_STUB is not set
755
756#
757# Miscellaneous I2C Chip support
758#
759# CONFIG_DS1682 is not set
760# CONFIG_SENSORS_PCF8574 is not set
761# CONFIG_PCF8575 is not set
762# CONFIG_SENSORS_PCA9539 is not set
763# CONFIG_SENSORS_TSL2550 is not set
764# CONFIG_I2C_DEBUG_CORE is not set
765# CONFIG_I2C_DEBUG_ALGO is not set
766# CONFIG_I2C_DEBUG_BUS is not set
767# CONFIG_I2C_DEBUG_CHIP is not set
768# CONFIG_SPI is not set
769CONFIG_ARCH_REQUIRE_GPIOLIB=y
770CONFIG_GPIOLIB=y
771CONFIG_GPIO_SYSFS=y
772
773#
774# Memory mapped GPIO expanders:
775#
776
777#
778# I2C GPIO expanders:
779#
780# CONFIG_GPIO_MAX732X is not set
781# CONFIG_GPIO_PCA953X is not set
782# CONFIG_GPIO_PCF857X is not set
783
784#
785# PCI GPIO expanders:
786#
787
788#
789# SPI GPIO expanders:
790#
791# CONFIG_W1 is not set
792# CONFIG_POWER_SUPPLY is not set
793# CONFIG_HWMON is not set
794# CONFIG_THERMAL is not set
795# CONFIG_THERMAL_HWMON is not set
796CONFIG_WATCHDOG=y
797CONFIG_WATCHDOG_NOWAYOUT=y
798
799#
800# Watchdog Device Drivers
801#
802# CONFIG_SOFT_WATCHDOG is not set
803CONFIG_AT91SAM9X_WATCHDOG=y
804
805#
806# USB-based Watchdog Cards
807#
808# CONFIG_USBPCWATCHDOG is not set
809CONFIG_SSB_POSSIBLE=y
810
811#
812# Sonics Silicon Backplane
813#
814# CONFIG_SSB is not set
815
816#
817# Multifunction device drivers
818#
819# CONFIG_MFD_CORE is not set
820# CONFIG_MFD_SM501 is not set
821# CONFIG_MFD_ASIC3 is not set
822# CONFIG_HTC_EGPIO is not set
823# CONFIG_HTC_PASIC3 is not set
824# CONFIG_TPS65010 is not set
825# CONFIG_TWL4030_CORE is not set
826# CONFIG_MFD_TMIO is not set
827# CONFIG_MFD_T7L66XB is not set
828# CONFIG_MFD_TC6387XB is not set
829# CONFIG_MFD_TC6393XB is not set
830# CONFIG_PMIC_DA903X is not set
831# CONFIG_MFD_WM8400 is not set
832# CONFIG_MFD_WM8350_I2C is not set
833# CONFIG_MFD_PCF50633 is not set
834# CONFIG_AB3100_CORE is not set
835# CONFIG_MEDIA_SUPPORT is not set
836
837#
838# Graphics support
839#
840# CONFIG_VGASTATE is not set
841# CONFIG_VIDEO_OUTPUT_CONTROL is not set
842# CONFIG_FB is not set
843# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
844
845#
846# Display device support
847#
848# CONFIG_DISPLAY_SUPPORT is not set
849
850#
851# Console display driver support
852#
853# CONFIG_VGA_CONSOLE is not set
854CONFIG_DUMMY_CONSOLE=y
855# CONFIG_SOUND is not set
856# CONFIG_HID_SUPPORT is not set
857CONFIG_USB_SUPPORT=y
858CONFIG_USB_ARCH_HAS_HCD=y
859CONFIG_USB_ARCH_HAS_OHCI=y
860# CONFIG_USB_ARCH_HAS_EHCI is not set
861CONFIG_USB=y
862# CONFIG_USB_DEBUG is not set
863# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
864
865#
866# Miscellaneous USB options
867#
868# CONFIG_USB_DEVICEFS is not set
869# CONFIG_USB_DEVICE_CLASS is not set
870# CONFIG_USB_DYNAMIC_MINORS is not set
871# CONFIG_USB_OTG is not set
872# CONFIG_USB_MON is not set
873# CONFIG_USB_WUSB is not set
874# CONFIG_USB_WUSB_CBAF is not set
875
876#
877# USB Host Controller Drivers
878#
879# CONFIG_USB_C67X00_HCD is not set
880# CONFIG_USB_OXU210HP_HCD is not set
881# CONFIG_USB_ISP116X_HCD is not set
882# CONFIG_USB_ISP1760_HCD is not set
883CONFIG_USB_OHCI_HCD=y
884# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
885# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
886CONFIG_USB_OHCI_LITTLE_ENDIAN=y
887# CONFIG_USB_SL811_HCD is not set
888# CONFIG_USB_R8A66597_HCD is not set
889# CONFIG_USB_HWA_HCD is not set
890# CONFIG_USB_MUSB_HDRC is not set
891# CONFIG_USB_GADGET_MUSB_HDRC is not set
892
893#
894# USB Device Class drivers
895#
896# CONFIG_USB_ACM is not set
897# CONFIG_USB_PRINTER is not set
898# CONFIG_USB_WDM is not set
899# CONFIG_USB_TMC is not set
900
901#
902# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
903#
904
905#
906# also be needed; see USB_STORAGE Help for more info
907#
908CONFIG_USB_STORAGE=y
909# CONFIG_USB_STORAGE_DEBUG is not set
910# CONFIG_USB_STORAGE_DATAFAB is not set
911# CONFIG_USB_STORAGE_FREECOM is not set
912# CONFIG_USB_STORAGE_ISD200 is not set
913# CONFIG_USB_STORAGE_USBAT is not set
914# CONFIG_USB_STORAGE_SDDR09 is not set
915# CONFIG_USB_STORAGE_SDDR55 is not set
916# CONFIG_USB_STORAGE_JUMPSHOT is not set
917# CONFIG_USB_STORAGE_ALAUDA is not set
918# CONFIG_USB_STORAGE_ONETOUCH is not set
919# CONFIG_USB_STORAGE_KARMA is not set
920# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
921# CONFIG_USB_LIBUSUAL is not set
922
923#
924# USB Imaging devices
925#
926# CONFIG_USB_MDC800 is not set
927# CONFIG_USB_MICROTEK is not set
928
929#
930# USB port drivers
931#
932# CONFIG_USB_SERIAL is not set
933
934#
935# USB Miscellaneous drivers
936#
937# CONFIG_USB_EMI62 is not set
938# CONFIG_USB_EMI26 is not set
939# CONFIG_USB_ADUTUX is not set
940# CONFIG_USB_SEVSEG is not set
941# CONFIG_USB_RIO500 is not set
942# CONFIG_USB_LEGOTOWER is not set
943# CONFIG_USB_LCD is not set
944# CONFIG_USB_BERRY_CHARGE is not set
945# CONFIG_USB_LED is not set
946# CONFIG_USB_CYPRESS_CY7C63 is not set
947# CONFIG_USB_CYTHERM is not set
948# CONFIG_USB_IDMOUSE is not set
949# CONFIG_USB_FTDI_ELAN is not set
950# CONFIG_USB_APPLEDISPLAY is not set
951# CONFIG_USB_LD is not set
952# CONFIG_USB_TRANCEVIBRATOR is not set
953# CONFIG_USB_IOWARRIOR is not set
954# CONFIG_USB_ISIGHTFW is not set
955# CONFIG_USB_VST is not set
956CONFIG_USB_GADGET=y
957# CONFIG_USB_GADGET_DEBUG_FILES is not set
958CONFIG_USB_GADGET_VBUS_DRAW=2
959CONFIG_USB_GADGET_SELECTED=y
960CONFIG_USB_GADGET_AT91=y
961CONFIG_USB_AT91=y
962# CONFIG_USB_GADGET_ATMEL_USBA is not set
963# CONFIG_USB_GADGET_FSL_USB2 is not set
964# CONFIG_USB_GADGET_LH7A40X is not set
965# CONFIG_USB_GADGET_OMAP is not set
966# CONFIG_USB_GADGET_PXA25X is not set
967# CONFIG_USB_GADGET_PXA27X is not set
968# CONFIG_USB_GADGET_S3C_HSOTG is not set
969# CONFIG_USB_GADGET_IMX is not set
970# CONFIG_USB_GADGET_S3C2410 is not set
971# CONFIG_USB_GADGET_M66592 is not set
972# CONFIG_USB_GADGET_AMD5536UDC is not set
973# CONFIG_USB_GADGET_FSL_QE is not set
974# CONFIG_USB_GADGET_CI13XXX is not set
975# CONFIG_USB_GADGET_NET2280 is not set
976# CONFIG_USB_GADGET_GOKU is not set
977# CONFIG_USB_GADGET_LANGWELL is not set
978# CONFIG_USB_GADGET_DUMMY_HCD is not set
979# CONFIG_USB_GADGET_DUALSPEED is not set
980# CONFIG_USB_ZERO is not set
981# CONFIG_USB_AUDIO is not set
982CONFIG_USB_ETH=y
983CONFIG_USB_ETH_RNDIS=y
984# CONFIG_USB_GADGETFS is not set
985# CONFIG_USB_FILE_STORAGE is not set
986# CONFIG_USB_G_SERIAL is not set
987# CONFIG_USB_MIDI_GADGET is not set
988# CONFIG_USB_G_PRINTER is not set
989# CONFIG_USB_CDC_COMPOSITE is not set
990
991#
992# OTG and related infrastructure
993#
994# CONFIG_USB_GPIO_VBUS is not set
995# CONFIG_NOP_USB_XCEIV is not set
996CONFIG_MMC=y
997# CONFIG_MMC_DEBUG is not set
998# CONFIG_MMC_UNSAFE_RESUME is not set
999
1000#
1001# MMC/SD/SDIO Card Drivers
1002#
1003CONFIG_MMC_BLOCK=y
1004CONFIG_MMC_BLOCK_BOUNCE=y
1005# CONFIG_SDIO_UART is not set
1006# CONFIG_MMC_TEST is not set
1007
1008#
1009# MMC/SD/SDIO Host Controller Drivers
1010#
1011# CONFIG_MMC_SDHCI is not set
1012CONFIG_MMC_AT91=y
1013# CONFIG_MEMSTICK is not set
1014# CONFIG_ACCESSIBILITY is not set
1015CONFIG_NEW_LEDS=y
1016CONFIG_LEDS_CLASS=y
1017
1018#
1019# LED drivers
1020#
1021# CONFIG_LEDS_PCA9532 is not set
1022CONFIG_LEDS_GPIO=y
1023CONFIG_LEDS_GPIO_PLATFORM=y
1024# CONFIG_LEDS_LP3944 is not set
1025# CONFIG_LEDS_PCA955X is not set
1026# CONFIG_LEDS_BD2802 is not set
1027
1028#
1029# LED Triggers
1030#
1031CONFIG_LEDS_TRIGGERS=y
1032CONFIG_LEDS_TRIGGER_TIMER=y
1033CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1034# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
1035CONFIG_LEDS_TRIGGER_GPIO=y
1036CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
1037
1038#
1039# iptables trigger is under Netfilter config (LED target)
1040#
1041CONFIG_RTC_LIB=y
1042CONFIG_RTC_CLASS=y
1043# CONFIG_RTC_HCTOSYS is not set
1044# CONFIG_RTC_DEBUG is not set
1045
1046#
1047# RTC interfaces
1048#
1049CONFIG_RTC_INTF_SYSFS=y
1050CONFIG_RTC_INTF_PROC=y
1051CONFIG_RTC_INTF_DEV=y
1052# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1053# CONFIG_RTC_DRV_TEST is not set
1054
1055#
1056# I2C RTC drivers
1057#
1058CONFIG_RTC_DRV_DS1307=y
1059# CONFIG_RTC_DRV_DS1374 is not set
1060# CONFIG_RTC_DRV_DS1672 is not set
1061# CONFIG_RTC_DRV_MAX6900 is not set
1062# CONFIG_RTC_DRV_RS5C372 is not set
1063# CONFIG_RTC_DRV_ISL1208 is not set
1064# CONFIG_RTC_DRV_X1205 is not set
1065# CONFIG_RTC_DRV_PCF8563 is not set
1066# CONFIG_RTC_DRV_PCF8583 is not set
1067# CONFIG_RTC_DRV_M41T80 is not set
1068# CONFIG_RTC_DRV_S35390A is not set
1069# CONFIG_RTC_DRV_FM3130 is not set
1070# CONFIG_RTC_DRV_RX8581 is not set
1071# CONFIG_RTC_DRV_RX8025 is not set
1072
1073#
1074# SPI RTC drivers
1075#
1076
1077#
1078# Platform RTC drivers
1079#
1080# CONFIG_RTC_DRV_CMOS is not set
1081# CONFIG_RTC_DRV_DS1286 is not set
1082# CONFIG_RTC_DRV_DS1511 is not set
1083# CONFIG_RTC_DRV_DS1553 is not set
1084# CONFIG_RTC_DRV_DS1742 is not set
1085# CONFIG_RTC_DRV_STK17TA8 is not set
1086# CONFIG_RTC_DRV_M48T86 is not set
1087# CONFIG_RTC_DRV_M48T35 is not set
1088# CONFIG_RTC_DRV_M48T59 is not set
1089# CONFIG_RTC_DRV_BQ4802 is not set
1090# CONFIG_RTC_DRV_V3020 is not set
1091
1092#
1093# on-CPU RTC drivers
1094#
1095# CONFIG_RTC_DRV_AT91SAM9 is not set
1096# CONFIG_DMADEVICES is not set
1097# CONFIG_AUXDISPLAY is not set
1098# CONFIG_REGULATOR is not set
1099# CONFIG_UIO is not set
1100# CONFIG_STAGING is not set
1101
1102#
1103# File systems
1104#
1105CONFIG_EXT2_FS=y
1106# CONFIG_EXT2_FS_XATTR is not set
1107# CONFIG_EXT2_FS_XIP is not set
1108CONFIG_EXT3_FS=y
1109# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
1110# CONFIG_EXT3_FS_XATTR is not set
1111# CONFIG_EXT4_FS is not set
1112CONFIG_JBD=y
1113# CONFIG_REISERFS_FS is not set
1114# CONFIG_JFS_FS is not set
1115# CONFIG_FS_POSIX_ACL is not set
1116# CONFIG_XFS_FS is not set
1117# CONFIG_GFS2_FS is not set
1118# CONFIG_OCFS2_FS is not set
1119# CONFIG_BTRFS_FS is not set
1120CONFIG_FILE_LOCKING=y
1121CONFIG_FSNOTIFY=y
1122CONFIG_DNOTIFY=y
1123CONFIG_INOTIFY=y
1124CONFIG_INOTIFY_USER=y
1125# CONFIG_QUOTA is not set
1126# CONFIG_AUTOFS_FS is not set
1127CONFIG_AUTOFS4_FS=y
1128# CONFIG_FUSE_FS is not set
1129
1130#
1131# Caches
1132#
1133# CONFIG_FSCACHE is not set
1134
1135#
1136# CD-ROM/DVD Filesystems
1137#
1138# CONFIG_ISO9660_FS is not set
1139# CONFIG_UDF_FS is not set
1140
1141#
1142# DOS/FAT/NT Filesystems
1143#
1144CONFIG_FAT_FS=y
1145CONFIG_MSDOS_FS=y
1146CONFIG_VFAT_FS=y
1147CONFIG_FAT_DEFAULT_CODEPAGE=437
1148CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1149# CONFIG_NTFS_FS is not set
1150
1151#
1152# Pseudo filesystems
1153#
1154CONFIG_PROC_FS=y
1155CONFIG_PROC_SYSCTL=y
1156CONFIG_PROC_PAGE_MONITOR=y
1157CONFIG_SYSFS=y
1158CONFIG_TMPFS=y
1159# CONFIG_TMPFS_POSIX_ACL is not set
1160# CONFIG_HUGETLB_PAGE is not set
1161# CONFIG_CONFIGFS_FS is not set
1162CONFIG_MISC_FILESYSTEMS=y
1163# CONFIG_ADFS_FS is not set
1164# CONFIG_AFFS_FS is not set
1165# CONFIG_HFS_FS is not set
1166# CONFIG_HFSPLUS_FS is not set
1167# CONFIG_BEFS_FS is not set
1168# CONFIG_BFS_FS is not set
1169# CONFIG_EFS_FS is not set
1170CONFIG_JFFS2_FS=y
1171CONFIG_JFFS2_FS_DEBUG=0
1172CONFIG_JFFS2_FS_WRITEBUFFER=y
1173# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1174CONFIG_JFFS2_SUMMARY=y
1175# CONFIG_JFFS2_FS_XATTR is not set
1176# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1177CONFIG_JFFS2_ZLIB=y
1178# CONFIG_JFFS2_LZO is not set
1179CONFIG_JFFS2_RTIME=y
1180# CONFIG_JFFS2_RUBIN is not set
1181CONFIG_CRAMFS=y
1182# CONFIG_SQUASHFS is not set
1183# CONFIG_VXFS_FS is not set
1184CONFIG_MINIX_FS=y
1185# CONFIG_OMFS_FS is not set
1186# CONFIG_HPFS_FS is not set
1187# CONFIG_QNX4FS_FS is not set
1188# CONFIG_ROMFS_FS is not set
1189# CONFIG_SYSV_FS is not set
1190# CONFIG_UFS_FS is not set
1191# CONFIG_NILFS2_FS is not set
1192CONFIG_NETWORK_FILESYSTEMS=y
1193CONFIG_NFS_FS=y
1194CONFIG_NFS_V3=y
1195# CONFIG_NFS_V3_ACL is not set
1196# CONFIG_NFS_V4 is not set
1197CONFIG_ROOT_NFS=y
1198# CONFIG_NFSD is not set
1199CONFIG_LOCKD=y
1200CONFIG_LOCKD_V4=y
1201CONFIG_NFS_COMMON=y
1202CONFIG_SUNRPC=y
1203# CONFIG_RPCSEC_GSS_KRB5 is not set
1204# CONFIG_RPCSEC_GSS_SPKM3 is not set
1205# CONFIG_SMB_FS is not set
1206# CONFIG_CIFS is not set
1207# CONFIG_NCP_FS is not set
1208# CONFIG_CODA_FS is not set
1209# CONFIG_AFS_FS is not set
1210
1211#
1212# Partition Types
1213#
1214CONFIG_PARTITION_ADVANCED=y
1215# CONFIG_ACORN_PARTITION is not set
1216# CONFIG_OSF_PARTITION is not set
1217# CONFIG_AMIGA_PARTITION is not set
1218# CONFIG_ATARI_PARTITION is not set
1219# CONFIG_MAC_PARTITION is not set
1220CONFIG_MSDOS_PARTITION=y
1221# CONFIG_BSD_DISKLABEL is not set
1222# CONFIG_MINIX_SUBPARTITION is not set
1223# CONFIG_SOLARIS_X86_PARTITION is not set
1224# CONFIG_UNIXWARE_DISKLABEL is not set
1225# CONFIG_LDM_PARTITION is not set
1226# CONFIG_SGI_PARTITION is not set
1227# CONFIG_ULTRIX_PARTITION is not set
1228# CONFIG_SUN_PARTITION is not set
1229# CONFIG_KARMA_PARTITION is not set
1230# CONFIG_EFI_PARTITION is not set
1231# CONFIG_SYSV68_PARTITION is not set
1232CONFIG_NLS=y
1233CONFIG_NLS_DEFAULT="iso8859-1"
1234CONFIG_NLS_CODEPAGE_437=y
1235# CONFIG_NLS_CODEPAGE_737 is not set
1236# CONFIG_NLS_CODEPAGE_775 is not set
1237# CONFIG_NLS_CODEPAGE_850 is not set
1238# CONFIG_NLS_CODEPAGE_852 is not set
1239# CONFIG_NLS_CODEPAGE_855 is not set
1240# CONFIG_NLS_CODEPAGE_857 is not set
1241# CONFIG_NLS_CODEPAGE_860 is not set
1242# CONFIG_NLS_CODEPAGE_861 is not set
1243# CONFIG_NLS_CODEPAGE_862 is not set
1244# CONFIG_NLS_CODEPAGE_863 is not set
1245# CONFIG_NLS_CODEPAGE_864 is not set
1246# CONFIG_NLS_CODEPAGE_865 is not set
1247# CONFIG_NLS_CODEPAGE_866 is not set
1248# CONFIG_NLS_CODEPAGE_869 is not set
1249# CONFIG_NLS_CODEPAGE_936 is not set
1250# CONFIG_NLS_CODEPAGE_950 is not set
1251# CONFIG_NLS_CODEPAGE_932 is not set
1252# CONFIG_NLS_CODEPAGE_949 is not set
1253# CONFIG_NLS_CODEPAGE_874 is not set
1254# CONFIG_NLS_ISO8859_8 is not set
1255# CONFIG_NLS_CODEPAGE_1250 is not set
1256# CONFIG_NLS_CODEPAGE_1251 is not set
1257# CONFIG_NLS_ASCII is not set
1258CONFIG_NLS_ISO8859_1=y
1259# CONFIG_NLS_ISO8859_2 is not set
1260# CONFIG_NLS_ISO8859_3 is not set
1261# CONFIG_NLS_ISO8859_4 is not set
1262# CONFIG_NLS_ISO8859_5 is not set
1263# CONFIG_NLS_ISO8859_6 is not set
1264# CONFIG_NLS_ISO8859_7 is not set
1265# CONFIG_NLS_ISO8859_9 is not set
1266# CONFIG_NLS_ISO8859_13 is not set
1267# CONFIG_NLS_ISO8859_14 is not set
1268# CONFIG_NLS_ISO8859_15 is not set
1269# CONFIG_NLS_KOI8_R is not set
1270# CONFIG_NLS_KOI8_U is not set
1271CONFIG_NLS_UTF8=y
1272# CONFIG_DLM is not set
1273
1274#
1275# Kernel hacking
1276#
1277# CONFIG_PRINTK_TIME is not set
1278CONFIG_ENABLE_WARN_DEPRECATED=y
1279CONFIG_ENABLE_MUST_CHECK=y
1280CONFIG_FRAME_WARN=1024
1281# CONFIG_MAGIC_SYSRQ is not set
1282# CONFIG_UNUSED_SYMBOLS is not set
1283# CONFIG_DEBUG_FS is not set
1284# CONFIG_HEADERS_CHECK is not set
1285# CONFIG_DEBUG_KERNEL is not set
1286# CONFIG_SLUB_DEBUG_ON is not set
1287# CONFIG_SLUB_STATS is not set
1288CONFIG_DEBUG_BUGVERBOSE=y
1289CONFIG_DEBUG_MEMORY_INIT=y
1290# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1291# CONFIG_LATENCYTOP is not set
1292# CONFIG_SYSCTL_SYSCALL_CHECK is not set
1293CONFIG_HAVE_FUNCTION_TRACER=y
1294CONFIG_TRACING_SUPPORT=y
1295# CONFIG_FTRACE is not set
1296# CONFIG_SAMPLES is not set
1297CONFIG_HAVE_ARCH_KGDB=y
1298CONFIG_ARM_UNWIND=y
1299# CONFIG_DEBUG_USER is not set
1300
1301#
1302# Security options
1303#
1304# CONFIG_KEYS is not set
1305# CONFIG_SECURITY is not set
1306# CONFIG_SECURITYFS is not set
1307# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1308# CONFIG_CRYPTO is not set
1309# CONFIG_BINARY_PRINTF is not set
1310
1311#
1312# Library routines
1313#
1314CONFIG_BITREVERSE=y
1315CONFIG_GENERIC_FIND_LAST_BIT=y
1316CONFIG_CRC_CCITT=y
1317# CONFIG_CRC16 is not set
1318# CONFIG_CRC_T10DIF is not set
1319# CONFIG_CRC_ITU_T is not set
1320CONFIG_CRC32=y
1321# CONFIG_CRC7 is not set
1322# CONFIG_LIBCRC32C is not set
1323CONFIG_ZLIB_INFLATE=y
1324CONFIG_ZLIB_DEFLATE=y
1325CONFIG_HAS_IOMEM=y
1326CONFIG_HAS_IOPORT=y
1327CONFIG_HAS_DMA=y
1328CONFIG_NLATTR=y
diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig
new file mode 100644
index 000000000000..4901827253fb
--- /dev/null
+++ b/arch/arm/configs/cpuat91_defconfig
@@ -0,0 +1,1316 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.31-rc3
4# Tue Jul 14 14:45:01 2009
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12CONFIG_GENERIC_HARDIRQS=y
13CONFIG_STACKTRACE_SUPPORT=y
14CONFIG_HAVE_LATENCYTOP_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20CONFIG_GENERIC_HWEIGHT=y
21CONFIG_GENERIC_CALIBRATE_DELAY=y
22CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
23CONFIG_VECTORS_BASE=0xffff0000
24CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
25CONFIG_CONSTRUCTORS=y
26
27#
28# General setup
29#
30CONFIG_EXPERIMENTAL=y
31CONFIG_BROKEN_ON_SMP=y
32CONFIG_LOCK_KERNEL=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36# CONFIG_SWAP is not set
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39# CONFIG_POSIX_MQUEUE is not set
40# CONFIG_BSD_PROCESS_ACCT is not set
41# CONFIG_TASKSTATS is not set
42# CONFIG_AUDIT is not set
43
44#
45# RCU Subsystem
46#
47CONFIG_CLASSIC_RCU=y
48# CONFIG_TREE_RCU is not set
49# CONFIG_PREEMPT_RCU is not set
50# CONFIG_TREE_RCU_TRACE is not set
51# CONFIG_PREEMPT_RCU_TRACE is not set
52# CONFIG_IKCONFIG is not set
53CONFIG_LOG_BUF_SHIFT=14
54# CONFIG_GROUP_SCHED is not set
55# CONFIG_CGROUPS is not set
56CONFIG_SYSFS_DEPRECATED=y
57CONFIG_SYSFS_DEPRECATED_V2=y
58# CONFIG_RELAY is not set
59CONFIG_NAMESPACES=y
60# CONFIG_UTS_NS is not set
61# CONFIG_IPC_NS is not set
62# CONFIG_USER_NS is not set
63# CONFIG_PID_NS is not set
64# CONFIG_NET_NS is not set
65# CONFIG_BLK_DEV_INITRD is not set
66CONFIG_CC_OPTIMIZE_FOR_SIZE=y
67CONFIG_SYSCTL=y
68CONFIG_ANON_INODES=y
69# CONFIG_EMBEDDED is not set
70CONFIG_UID16=y
71CONFIG_SYSCTL_SYSCALL=y
72CONFIG_KALLSYMS=y
73# CONFIG_KALLSYMS_EXTRA_PASS is not set
74CONFIG_HOTPLUG=y
75CONFIG_PRINTK=y
76CONFIG_BUG=y
77CONFIG_ELF_CORE=y
78CONFIG_BASE_FULL=y
79CONFIG_FUTEX=y
80CONFIG_EPOLL=y
81CONFIG_SIGNALFD=y
82CONFIG_TIMERFD=y
83CONFIG_EVENTFD=y
84CONFIG_SHMEM=y
85CONFIG_AIO=y
86
87#
88# Performance Counters
89#
90CONFIG_VM_EVENT_COUNTERS=y
91CONFIG_SLUB_DEBUG=y
92# CONFIG_STRIP_ASM_SYMS is not set
93CONFIG_COMPAT_BRK=y
94# CONFIG_SLAB is not set
95CONFIG_SLUB=y
96# CONFIG_SLOB is not set
97# CONFIG_PROFILING is not set
98# CONFIG_MARKERS is not set
99CONFIG_HAVE_OPROFILE=y
100# CONFIG_KPROBES is not set
101CONFIG_HAVE_KPROBES=y
102CONFIG_HAVE_KRETPROBES=y
103CONFIG_HAVE_CLK=y
104
105#
106# GCOV-based kernel profiling
107#
108# CONFIG_SLOW_WORK is not set
109CONFIG_HAVE_GENERIC_DMA_COHERENT=y
110CONFIG_SLABINFO=y
111CONFIG_RT_MUTEXES=y
112CONFIG_BASE_SMALL=0
113CONFIG_MODULES=y
114# CONFIG_MODULE_FORCE_LOAD is not set
115CONFIG_MODULE_UNLOAD=y
116# CONFIG_MODULE_FORCE_UNLOAD is not set
117# CONFIG_MODVERSIONS is not set
118# CONFIG_MODULE_SRCVERSION_ALL is not set
119CONFIG_BLOCK=y
120CONFIG_LBDAF=y
121# CONFIG_BLK_DEV_BSG is not set
122# CONFIG_BLK_DEV_INTEGRITY is not set
123
124#
125# IO Schedulers
126#
127CONFIG_IOSCHED_NOOP=y
128# CONFIG_IOSCHED_AS is not set
129CONFIG_IOSCHED_DEADLINE=y
130# CONFIG_IOSCHED_CFQ is not set
131# CONFIG_DEFAULT_AS is not set
132CONFIG_DEFAULT_DEADLINE=y
133# CONFIG_DEFAULT_CFQ is not set
134# CONFIG_DEFAULT_NOOP is not set
135CONFIG_DEFAULT_IOSCHED="deadline"
136# CONFIG_FREEZER is not set
137
138#
139# System Type
140#
141# CONFIG_ARCH_AAEC2000 is not set
142# CONFIG_ARCH_INTEGRATOR is not set
143# CONFIG_ARCH_REALVIEW is not set
144# CONFIG_ARCH_VERSATILE is not set
145CONFIG_ARCH_AT91=y
146# CONFIG_ARCH_CLPS711X is not set
147# CONFIG_ARCH_GEMINI is not set
148# CONFIG_ARCH_EBSA110 is not set
149# CONFIG_ARCH_EP93XX is not set
150# CONFIG_ARCH_FOOTBRIDGE is not set
151# CONFIG_ARCH_MXC is not set
152# CONFIG_ARCH_STMP3XXX is not set
153# CONFIG_ARCH_NETX is not set
154# CONFIG_ARCH_H720X is not set
155# CONFIG_ARCH_IOP13XX is not set
156# CONFIG_ARCH_IOP32X is not set
157# CONFIG_ARCH_IOP33X is not set
158# CONFIG_ARCH_IXP23XX is not set
159# CONFIG_ARCH_IXP2000 is not set
160# CONFIG_ARCH_IXP4XX is not set
161# CONFIG_ARCH_L7200 is not set
162# CONFIG_ARCH_KIRKWOOD is not set
163# CONFIG_ARCH_LOKI is not set
164# CONFIG_ARCH_MV78XX0 is not set
165# CONFIG_ARCH_ORION5X is not set
166# CONFIG_ARCH_MMP is not set
167# CONFIG_ARCH_KS8695 is not set
168# CONFIG_ARCH_NS9XXX is not set
169# CONFIG_ARCH_W90X900 is not set
170# CONFIG_ARCH_PNX4008 is not set
171# CONFIG_ARCH_PXA is not set
172# CONFIG_ARCH_MSM is not set
173# CONFIG_ARCH_RPC is not set
174# CONFIG_ARCH_SA1100 is not set
175# CONFIG_ARCH_S3C2410 is not set
176# CONFIG_ARCH_S3C64XX is not set
177# CONFIG_ARCH_SHARK is not set
178# CONFIG_ARCH_LH7A40X is not set
179# CONFIG_ARCH_U300 is not set
180# CONFIG_ARCH_DAVINCI is not set
181# CONFIG_ARCH_OMAP is not set
182
183#
184# Atmel AT91 System-on-Chip
185#
186CONFIG_ARCH_AT91RM9200=y
187# CONFIG_ARCH_AT91SAM9260 is not set
188# CONFIG_ARCH_AT91SAM9261 is not set
189# CONFIG_ARCH_AT91SAM9263 is not set
190# CONFIG_ARCH_AT91SAM9RL is not set
191# CONFIG_ARCH_AT91SAM9G20 is not set
192# CONFIG_ARCH_AT91CAP9 is not set
193# CONFIG_ARCH_AT91X40 is not set
194CONFIG_AT91_PMC_UNIT=y
195
196#
197# AT91RM9200 Board Type
198#
199# CONFIG_MACH_ONEARM is not set
200# CONFIG_ARCH_AT91RM9200DK is not set
201# CONFIG_MACH_AT91RM9200EK is not set
202# CONFIG_MACH_CSB337 is not set
203# CONFIG_MACH_CSB637 is not set
204# CONFIG_MACH_CARMEVA is not set
205# CONFIG_MACH_ATEB9200 is not set
206# CONFIG_MACH_KB9200 is not set
207# CONFIG_MACH_PICOTUX2XX is not set
208# CONFIG_MACH_KAFA is not set
209# CONFIG_MACH_ECBAT91 is not set
210# CONFIG_MACH_YL9200 is not set
211CONFIG_MACH_CPUAT91=y
212
213#
214# AT91 Board Options
215#
216
217#
218# AT91 Feature Selections
219#
220# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
221CONFIG_AT91_TIMER_HZ=100
222CONFIG_AT91_EARLY_DBGU=y
223# CONFIG_AT91_EARLY_USART0 is not set
224# CONFIG_AT91_EARLY_USART1 is not set
225# CONFIG_AT91_EARLY_USART2 is not set
226# CONFIG_AT91_EARLY_USART3 is not set
227# CONFIG_AT91_EARLY_USART4 is not set
228# CONFIG_AT91_EARLY_USART5 is not set
229
230#
231# Processor Type
232#
233CONFIG_CPU_32=y
234CONFIG_CPU_ARM920T=y
235CONFIG_CPU_32v4T=y
236CONFIG_CPU_ABRT_EV4T=y
237CONFIG_CPU_PABRT_NOIFAR=y
238CONFIG_CPU_CACHE_V4WT=y
239CONFIG_CPU_CACHE_VIVT=y
240CONFIG_CPU_COPY_V4WB=y
241CONFIG_CPU_TLB_V4WBI=y
242CONFIG_CPU_CP15=y
243CONFIG_CPU_CP15_MMU=y
244
245#
246# Processor Features
247#
248# CONFIG_ARM_THUMB is not set
249# CONFIG_CPU_ICACHE_DISABLE is not set
250# CONFIG_CPU_DCACHE_DISABLE is not set
251# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
252
253#
254# Bus support
255#
256# CONFIG_PCI_SYSCALL is not set
257# CONFIG_ARCH_SUPPORTS_MSI is not set
258# CONFIG_PCCARD is not set
259
260#
261# Kernel Features
262#
263# CONFIG_NO_HZ is not set
264# CONFIG_HIGH_RES_TIMERS is not set
265CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
266CONFIG_VMSPLIT_3G=y
267# CONFIG_VMSPLIT_2G is not set
268# CONFIG_VMSPLIT_1G is not set
269CONFIG_PAGE_OFFSET=0xC0000000
270CONFIG_PREEMPT=y
271CONFIG_HZ=100
272# CONFIG_AEABI is not set
273# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
274# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
275# CONFIG_HIGHMEM is not set
276CONFIG_SELECT_MEMORY_MODEL=y
277CONFIG_FLATMEM_MANUAL=y
278# CONFIG_DISCONTIGMEM_MANUAL is not set
279# CONFIG_SPARSEMEM_MANUAL is not set
280CONFIG_FLATMEM=y
281CONFIG_FLAT_NODE_MEM_MAP=y
282CONFIG_PAGEFLAGS_EXTENDED=y
283CONFIG_SPLIT_PTLOCK_CPUS=4096
284# CONFIG_PHYS_ADDR_T_64BIT is not set
285CONFIG_ZONE_DMA_FLAG=0
286CONFIG_VIRT_TO_BUS=y
287CONFIG_HAVE_MLOCK=y
288CONFIG_HAVE_MLOCKED_PAGE_BIT=y
289CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
290# CONFIG_LEDS is not set
291CONFIG_ALIGNMENT_TRAP=y
292# CONFIG_UACCESS_WITH_MEMCPY is not set
293
294#
295# Boot options
296#
297CONFIG_ZBOOT_ROM_TEXT=0x0
298CONFIG_ZBOOT_ROM_BSS=0x0
299CONFIG_CMDLINE=""
300# CONFIG_XIP_KERNEL is not set
301# CONFIG_KEXEC is not set
302
303#
304# CPU Power Management
305#
306# CONFIG_CPU_IDLE is not set
307
308#
309# Floating point emulation
310#
311
312#
313# At least one emulation must be selected
314#
315# CONFIG_FPE_NWFPE is not set
316# CONFIG_FPE_FASTFPE is not set
317
318#
319# Userspace binary formats
320#
321CONFIG_BINFMT_ELF=y
322# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
323CONFIG_HAVE_AOUT=y
324# CONFIG_BINFMT_AOUT is not set
325# CONFIG_BINFMT_MISC is not set
326# CONFIG_ARTHUR is not set
327
328#
329# Power management options
330#
331# CONFIG_PM is not set
332CONFIG_ARCH_SUSPEND_POSSIBLE=y
333CONFIG_NET=y
334
335#
336# Networking options
337#
338CONFIG_PACKET=y
339# CONFIG_PACKET_MMAP is not set
340CONFIG_UNIX=y
341# CONFIG_NET_KEY is not set
342CONFIG_INET=y
343# CONFIG_IP_MULTICAST is not set
344# CONFIG_IP_ADVANCED_ROUTER is not set
345CONFIG_IP_FIB_HASH=y
346CONFIG_IP_PNP=y
347# CONFIG_IP_PNP_DHCP is not set
348# CONFIG_IP_PNP_BOOTP is not set
349# CONFIG_IP_PNP_RARP is not set
350# CONFIG_NET_IPIP is not set
351# CONFIG_NET_IPGRE is not set
352# CONFIG_ARPD is not set
353# CONFIG_SYN_COOKIES is not set
354# CONFIG_INET_AH is not set
355# CONFIG_INET_ESP is not set
356# CONFIG_INET_IPCOMP is not set
357# CONFIG_INET_XFRM_TUNNEL is not set
358# CONFIG_INET_TUNNEL is not set
359# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
360# CONFIG_INET_XFRM_MODE_TUNNEL is not set
361# CONFIG_INET_XFRM_MODE_BEET is not set
362CONFIG_INET_LRO=y
363CONFIG_INET_DIAG=y
364CONFIG_INET_TCP_DIAG=y
365# CONFIG_TCP_CONG_ADVANCED is not set
366CONFIG_TCP_CONG_CUBIC=y
367CONFIG_DEFAULT_TCP_CONG="cubic"
368# CONFIG_TCP_MD5SIG is not set
369# CONFIG_IPV6 is not set
370# CONFIG_NETWORK_SECMARK is not set
371# CONFIG_NETFILTER is not set
372# CONFIG_IP_DCCP is not set
373# CONFIG_IP_SCTP is not set
374# CONFIG_TIPC is not set
375# CONFIG_ATM is not set
376# CONFIG_BRIDGE is not set
377# CONFIG_NET_DSA is not set
378# CONFIG_VLAN_8021Q is not set
379# CONFIG_DECNET is not set
380# CONFIG_LLC2 is not set
381# CONFIG_IPX is not set
382# CONFIG_ATALK is not set
383# CONFIG_X25 is not set
384# CONFIG_LAPB is not set
385# CONFIG_ECONET is not set
386# CONFIG_WAN_ROUTER is not set
387# CONFIG_PHONET is not set
388# CONFIG_IEEE802154 is not set
389# CONFIG_NET_SCHED is not set
390# CONFIG_DCB is not set
391
392#
393# Network testing
394#
395# CONFIG_NET_PKTGEN is not set
396# CONFIG_HAMRADIO is not set
397# CONFIG_CAN is not set
398# CONFIG_IRDA is not set
399# CONFIG_BT is not set
400# CONFIG_AF_RXRPC is not set
401# CONFIG_WIRELESS is not set
402# CONFIG_WIMAX is not set
403# CONFIG_RFKILL is not set
404# CONFIG_NET_9P is not set
405
406#
407# Device Drivers
408#
409
410#
411# Generic Driver Options
412#
413CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
414CONFIG_STANDALONE=y
415CONFIG_PREVENT_FIRMWARE_BUILD=y
416CONFIG_FW_LOADER=y
417CONFIG_FIRMWARE_IN_KERNEL=y
418CONFIG_EXTRA_FIRMWARE=""
419# CONFIG_SYS_HYPERVISOR is not set
420# CONFIG_CONNECTOR is not set
421CONFIG_MTD=y
422# CONFIG_MTD_DEBUG is not set
423# CONFIG_MTD_CONCAT is not set
424CONFIG_MTD_PARTITIONS=y
425# CONFIG_MTD_TESTS is not set
426# CONFIG_MTD_REDBOOT_PARTS is not set
427CONFIG_MTD_CMDLINE_PARTS=y
428# CONFIG_MTD_AFS_PARTS is not set
429# CONFIG_MTD_AR7_PARTS is not set
430
431#
432# User Modules And Translation Layers
433#
434CONFIG_MTD_CHAR=y
435CONFIG_MTD_BLKDEVS=y
436CONFIG_MTD_BLOCK=y
437# CONFIG_FTL is not set
438# CONFIG_NFTL is not set
439# CONFIG_INFTL is not set
440# CONFIG_RFD_FTL is not set
441# CONFIG_SSFDC is not set
442# CONFIG_MTD_OOPS is not set
443
444#
445# RAM/ROM/Flash chip drivers
446#
447CONFIG_MTD_CFI=y
448# CONFIG_MTD_JEDECPROBE is not set
449CONFIG_MTD_GEN_PROBE=y
450# CONFIG_MTD_CFI_ADV_OPTIONS is not set
451CONFIG_MTD_MAP_BANK_WIDTH_1=y
452CONFIG_MTD_MAP_BANK_WIDTH_2=y
453CONFIG_MTD_MAP_BANK_WIDTH_4=y
454# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
455# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
456# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
457CONFIG_MTD_CFI_I1=y
458CONFIG_MTD_CFI_I2=y
459# CONFIG_MTD_CFI_I4 is not set
460# CONFIG_MTD_CFI_I8 is not set
461CONFIG_MTD_CFI_INTELEXT=y
462# CONFIG_MTD_CFI_AMDSTD is not set
463# CONFIG_MTD_CFI_STAA is not set
464CONFIG_MTD_CFI_UTIL=y
465CONFIG_MTD_RAM=y
466# CONFIG_MTD_ROM is not set
467# CONFIG_MTD_ABSENT is not set
468
469#
470# Mapping drivers for chip access
471#
472# CONFIG_MTD_COMPLEX_MAPPINGS is not set
473CONFIG_MTD_PHYSMAP=y
474# CONFIG_MTD_PHYSMAP_COMPAT is not set
475# CONFIG_MTD_ARM_INTEGRATOR is not set
476CONFIG_MTD_PLATRAM=y
477
478#
479# Self-contained MTD device drivers
480#
481# CONFIG_MTD_SLRAM is not set
482# CONFIG_MTD_PHRAM is not set
483# CONFIG_MTD_MTDRAM is not set
484# CONFIG_MTD_BLOCK2MTD is not set
485
486#
487# Disk-On-Chip Device Drivers
488#
489# CONFIG_MTD_DOC2000 is not set
490# CONFIG_MTD_DOC2001 is not set
491# CONFIG_MTD_DOC2001PLUS is not set
492# CONFIG_MTD_NAND is not set
493# CONFIG_MTD_ONENAND is not set
494
495#
496# LPDDR flash memory drivers
497#
498# CONFIG_MTD_LPDDR is not set
499
500#
501# UBI - Unsorted block images
502#
503# CONFIG_MTD_UBI is not set
504# CONFIG_PARPORT is not set
505CONFIG_BLK_DEV=y
506# CONFIG_BLK_DEV_COW_COMMON is not set
507CONFIG_BLK_DEV_LOOP=y
508# CONFIG_BLK_DEV_CRYPTOLOOP is not set
509CONFIG_BLK_DEV_NBD=y
510# CONFIG_BLK_DEV_UB is not set
511CONFIG_BLK_DEV_RAM=y
512CONFIG_BLK_DEV_RAM_COUNT=16
513CONFIG_BLK_DEV_RAM_SIZE=4096
514# CONFIG_BLK_DEV_XIP is not set
515# CONFIG_CDROM_PKTCDVD is not set
516# CONFIG_ATA_OVER_ETH is not set
517# CONFIG_MG_DISK is not set
518# CONFIG_MISC_DEVICES is not set
519CONFIG_HAVE_IDE=y
520# CONFIG_IDE is not set
521
522#
523# SCSI device support
524#
525# CONFIG_RAID_ATTRS is not set
526CONFIG_SCSI=y
527CONFIG_SCSI_DMA=y
528# CONFIG_SCSI_TGT is not set
529# CONFIG_SCSI_NETLINK is not set
530CONFIG_SCSI_PROC_FS=y
531
532#
533# SCSI support type (disk, tape, CD-ROM)
534#
535CONFIG_BLK_DEV_SD=y
536# CONFIG_CHR_DEV_ST is not set
537# CONFIG_CHR_DEV_OSST is not set
538# CONFIG_BLK_DEV_SR is not set
539# CONFIG_CHR_DEV_SG is not set
540# CONFIG_CHR_DEV_SCH is not set
541CONFIG_SCSI_MULTI_LUN=y
542# CONFIG_SCSI_CONSTANTS is not set
543# CONFIG_SCSI_LOGGING is not set
544# CONFIG_SCSI_SCAN_ASYNC is not set
545CONFIG_SCSI_WAIT_SCAN=m
546
547#
548# SCSI Transports
549#
550# CONFIG_SCSI_SPI_ATTRS is not set
551# CONFIG_SCSI_FC_ATTRS is not set
552# CONFIG_SCSI_ISCSI_ATTRS is not set
553# CONFIG_SCSI_SAS_LIBSAS is not set
554# CONFIG_SCSI_SRP_ATTRS is not set
555# CONFIG_SCSI_LOWLEVEL is not set
556# CONFIG_SCSI_DH is not set
557# CONFIG_SCSI_OSD_INITIATOR is not set
558# CONFIG_ATA is not set
559# CONFIG_MD is not set
560CONFIG_NETDEVICES=y
561# CONFIG_DUMMY is not set
562# CONFIG_BONDING is not set
563# CONFIG_MACVLAN is not set
564# CONFIG_EQUALIZER is not set
565# CONFIG_TUN is not set
566# CONFIG_VETH is not set
567CONFIG_PHYLIB=y
568
569#
570# MII PHY device drivers
571#
572# CONFIG_MARVELL_PHY is not set
573# CONFIG_DAVICOM_PHY is not set
574# CONFIG_QSEMI_PHY is not set
575# CONFIG_LXT_PHY is not set
576# CONFIG_CICADA_PHY is not set
577# CONFIG_VITESSE_PHY is not set
578# CONFIG_SMSC_PHY is not set
579# CONFIG_BROADCOM_PHY is not set
580# CONFIG_ICPLUS_PHY is not set
581# CONFIG_REALTEK_PHY is not set
582# CONFIG_NATIONAL_PHY is not set
583# CONFIG_STE10XP is not set
584# CONFIG_LSI_ET1011C_PHY is not set
585# CONFIG_FIXED_PHY is not set
586# CONFIG_MDIO_BITBANG is not set
587CONFIG_NET_ETHERNET=y
588CONFIG_MII=y
589CONFIG_ARM_AT91_ETHER=y
590# CONFIG_AX88796 is not set
591# CONFIG_SMC91X is not set
592# CONFIG_DM9000 is not set
593# CONFIG_ETHOC is not set
594# CONFIG_SMC911X is not set
595# CONFIG_SMSC911X is not set
596# CONFIG_DNET is not set
597# CONFIG_IBM_NEW_EMAC_ZMII is not set
598# CONFIG_IBM_NEW_EMAC_RGMII is not set
599# CONFIG_IBM_NEW_EMAC_TAH is not set
600# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
601# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
602# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
603# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
604# CONFIG_B44 is not set
605# CONFIG_KS8842 is not set
606# CONFIG_NETDEV_1000 is not set
607# CONFIG_NETDEV_10000 is not set
608
609#
610# Wireless LAN
611#
612# CONFIG_WLAN_PRE80211 is not set
613# CONFIG_WLAN_80211 is not set
614
615#
616# Enable WiMAX (Networking options) to see the WiMAX drivers
617#
618
619#
620# USB Network Adapters
621#
622# CONFIG_USB_CATC is not set
623# CONFIG_USB_KAWETH is not set
624# CONFIG_USB_PEGASUS is not set
625# CONFIG_USB_RTL8150 is not set
626# CONFIG_USB_USBNET is not set
627# CONFIG_WAN is not set
628CONFIG_PPP=y
629# CONFIG_PPP_MULTILINK is not set
630# CONFIG_PPP_FILTER is not set
631CONFIG_PPP_ASYNC=y
632# CONFIG_PPP_SYNC_TTY is not set
633CONFIG_PPP_DEFLATE=y
634CONFIG_PPP_BSDCOMP=y
635# CONFIG_PPP_MPPE is not set
636# CONFIG_PPPOE is not set
637# CONFIG_PPPOL2TP is not set
638# CONFIG_SLIP is not set
639CONFIG_SLHC=y
640# CONFIG_NETCONSOLE is not set
641# CONFIG_NETPOLL is not set
642# CONFIG_NET_POLL_CONTROLLER is not set
643# CONFIG_ISDN is not set
644
645#
646# Input device support
647#
648CONFIG_INPUT=y
649# CONFIG_INPUT_FF_MEMLESS is not set
650# CONFIG_INPUT_POLLDEV is not set
651
652#
653# Userland interfaces
654#
655CONFIG_INPUT_MOUSEDEV=y
656# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
657CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
658CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
659# CONFIG_INPUT_JOYDEV is not set
660# CONFIG_INPUT_EVDEV is not set
661# CONFIG_INPUT_EVBUG is not set
662
663#
664# Input Device Drivers
665#
666# CONFIG_INPUT_KEYBOARD is not set
667# CONFIG_INPUT_MOUSE is not set
668# CONFIG_INPUT_JOYSTICK is not set
669# CONFIG_INPUT_TABLET is not set
670# CONFIG_INPUT_TOUCHSCREEN is not set
671# CONFIG_INPUT_MISC is not set
672
673#
674# Hardware I/O ports
675#
676# CONFIG_SERIO is not set
677# CONFIG_GAMEPORT is not set
678
679#
680# Character devices
681#
682CONFIG_VT=y
683CONFIG_CONSOLE_TRANSLATIONS=y
684CONFIG_VT_CONSOLE=y
685CONFIG_HW_CONSOLE=y
686# CONFIG_VT_HW_CONSOLE_BINDING is not set
687CONFIG_DEVKMEM=y
688# CONFIG_SERIAL_NONSTANDARD is not set
689
690#
691# Serial drivers
692#
693# CONFIG_SERIAL_8250 is not set
694
695#
696# Non-8250 serial port support
697#
698CONFIG_SERIAL_ATMEL=y
699CONFIG_SERIAL_ATMEL_CONSOLE=y
700CONFIG_SERIAL_ATMEL_PDC=y
701# CONFIG_SERIAL_ATMEL_TTYAT is not set
702CONFIG_SERIAL_CORE=y
703CONFIG_SERIAL_CORE_CONSOLE=y
704CONFIG_UNIX98_PTYS=y
705# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
706CONFIG_LEGACY_PTYS=y
707CONFIG_LEGACY_PTY_COUNT=32
708# CONFIG_IPMI_HANDLER is not set
709# CONFIG_HW_RANDOM is not set
710# CONFIG_R3964 is not set
711# CONFIG_RAW_DRIVER is not set
712# CONFIG_TCG_TPM is not set
713CONFIG_I2C=y
714CONFIG_I2C_BOARDINFO=y
715CONFIG_I2C_CHARDEV=y
716CONFIG_I2C_HELPER_AUTO=y
717CONFIG_I2C_ALGOBIT=y
718
719#
720# I2C Hardware Bus support
721#
722
723#
724# I2C system bus drivers (mostly embedded / system-on-chip)
725#
726# CONFIG_I2C_DESIGNWARE is not set
727CONFIG_I2C_GPIO=y
728# CONFIG_I2C_OCORES is not set
729# CONFIG_I2C_SIMTEC is not set
730
731#
732# External I2C/SMBus adapter drivers
733#
734# CONFIG_I2C_PARPORT_LIGHT is not set
735# CONFIG_I2C_TAOS_EVM is not set
736# CONFIG_I2C_TINY_USB is not set
737
738#
739# Other I2C/SMBus bus drivers
740#
741# CONFIG_I2C_PCA_PLATFORM is not set
742# CONFIG_I2C_STUB is not set
743
744#
745# Miscellaneous I2C Chip support
746#
747# CONFIG_DS1682 is not set
748# CONFIG_SENSORS_PCF8574 is not set
749# CONFIG_PCF8575 is not set
750# CONFIG_SENSORS_PCA9539 is not set
751# CONFIG_SENSORS_TSL2550 is not set
752# CONFIG_I2C_DEBUG_CORE is not set
753# CONFIG_I2C_DEBUG_ALGO is not set
754# CONFIG_I2C_DEBUG_BUS is not set
755# CONFIG_I2C_DEBUG_CHIP is not set
756# CONFIG_SPI is not set
757CONFIG_ARCH_REQUIRE_GPIOLIB=y
758CONFIG_GPIOLIB=y
759CONFIG_GPIO_SYSFS=y
760
761#
762# Memory mapped GPIO expanders:
763#
764
765#
766# I2C GPIO expanders:
767#
768# CONFIG_GPIO_MAX732X is not set
769# CONFIG_GPIO_PCA953X is not set
770# CONFIG_GPIO_PCF857X is not set
771
772#
773# PCI GPIO expanders:
774#
775
776#
777# SPI GPIO expanders:
778#
779# CONFIG_W1 is not set
780# CONFIG_POWER_SUPPLY is not set
781# CONFIG_HWMON is not set
782# CONFIG_THERMAL is not set
783# CONFIG_THERMAL_HWMON is not set
784CONFIG_WATCHDOG=y
785CONFIG_WATCHDOG_NOWAYOUT=y
786
787#
788# Watchdog Device Drivers
789#
790# CONFIG_SOFT_WATCHDOG is not set
791CONFIG_AT91RM9200_WATCHDOG=y
792
793#
794# USB-based Watchdog Cards
795#
796# CONFIG_USBPCWATCHDOG is not set
797CONFIG_SSB_POSSIBLE=y
798
799#
800# Sonics Silicon Backplane
801#
802# CONFIG_SSB is not set
803
804#
805# Multifunction device drivers
806#
807# CONFIG_MFD_CORE is not set
808# CONFIG_MFD_SM501 is not set
809# CONFIG_MFD_ASIC3 is not set
810# CONFIG_HTC_EGPIO is not set
811# CONFIG_HTC_PASIC3 is not set
812# CONFIG_TPS65010 is not set
813# CONFIG_TWL4030_CORE is not set
814# CONFIG_MFD_TMIO is not set
815# CONFIG_MFD_T7L66XB is not set
816# CONFIG_MFD_TC6387XB is not set
817# CONFIG_MFD_TC6393XB is not set
818# CONFIG_PMIC_DA903X is not set
819# CONFIG_MFD_WM8400 is not set
820# CONFIG_MFD_WM8350_I2C is not set
821# CONFIG_MFD_PCF50633 is not set
822# CONFIG_AB3100_CORE is not set
823# CONFIG_MEDIA_SUPPORT is not set
824
825#
826# Graphics support
827#
828# CONFIG_VGASTATE is not set
829# CONFIG_VIDEO_OUTPUT_CONTROL is not set
830# CONFIG_FB is not set
831# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
832
833#
834# Display device support
835#
836# CONFIG_DISPLAY_SUPPORT is not set
837
838#
839# Console display driver support
840#
841# CONFIG_VGA_CONSOLE is not set
842CONFIG_DUMMY_CONSOLE=y
843# CONFIG_SOUND is not set
844# CONFIG_HID_SUPPORT is not set
845CONFIG_USB_SUPPORT=y
846CONFIG_USB_ARCH_HAS_HCD=y
847CONFIG_USB_ARCH_HAS_OHCI=y
848# CONFIG_USB_ARCH_HAS_EHCI is not set
849CONFIG_USB=y
850# CONFIG_USB_DEBUG is not set
851# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
852
853#
854# Miscellaneous USB options
855#
856# CONFIG_USB_DEVICEFS is not set
857# CONFIG_USB_DEVICE_CLASS is not set
858# CONFIG_USB_DYNAMIC_MINORS is not set
859# CONFIG_USB_OTG is not set
860# CONFIG_USB_MON is not set
861# CONFIG_USB_WUSB is not set
862# CONFIG_USB_WUSB_CBAF is not set
863
864#
865# USB Host Controller Drivers
866#
867# CONFIG_USB_C67X00_HCD is not set
868# CONFIG_USB_OXU210HP_HCD is not set
869# CONFIG_USB_ISP116X_HCD is not set
870# CONFIG_USB_ISP1760_HCD is not set
871CONFIG_USB_OHCI_HCD=y
872# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
873# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
874CONFIG_USB_OHCI_LITTLE_ENDIAN=y
875# CONFIG_USB_SL811_HCD is not set
876# CONFIG_USB_R8A66597_HCD is not set
877# CONFIG_USB_HWA_HCD is not set
878# CONFIG_USB_MUSB_HDRC is not set
879# CONFIG_USB_GADGET_MUSB_HDRC is not set
880
881#
882# USB Device Class drivers
883#
884# CONFIG_USB_ACM is not set
885# CONFIG_USB_PRINTER is not set
886# CONFIG_USB_WDM is not set
887# CONFIG_USB_TMC is not set
888
889#
890# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
891#
892
893#
894# also be needed; see USB_STORAGE Help for more info
895#
896CONFIG_USB_STORAGE=y
897# CONFIG_USB_STORAGE_DEBUG is not set
898# CONFIG_USB_STORAGE_DATAFAB is not set
899# CONFIG_USB_STORAGE_FREECOM is not set
900# CONFIG_USB_STORAGE_ISD200 is not set
901# CONFIG_USB_STORAGE_USBAT is not set
902# CONFIG_USB_STORAGE_SDDR09 is not set
903# CONFIG_USB_STORAGE_SDDR55 is not set
904# CONFIG_USB_STORAGE_JUMPSHOT is not set
905# CONFIG_USB_STORAGE_ALAUDA is not set
906# CONFIG_USB_STORAGE_ONETOUCH is not set
907# CONFIG_USB_STORAGE_KARMA is not set
908# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
909# CONFIG_USB_LIBUSUAL is not set
910
911#
912# USB Imaging devices
913#
914# CONFIG_USB_MDC800 is not set
915# CONFIG_USB_MICROTEK is not set
916
917#
918# USB port drivers
919#
920# CONFIG_USB_SERIAL is not set
921
922#
923# USB Miscellaneous drivers
924#
925# CONFIG_USB_EMI62 is not set
926# CONFIG_USB_EMI26 is not set
927# CONFIG_USB_ADUTUX is not set
928# CONFIG_USB_SEVSEG is not set
929# CONFIG_USB_RIO500 is not set
930# CONFIG_USB_LEGOTOWER is not set
931# CONFIG_USB_LCD is not set
932# CONFIG_USB_BERRY_CHARGE is not set
933# CONFIG_USB_LED is not set
934# CONFIG_USB_CYPRESS_CY7C63 is not set
935# CONFIG_USB_CYTHERM is not set
936# CONFIG_USB_IDMOUSE is not set
937# CONFIG_USB_FTDI_ELAN is not set
938# CONFIG_USB_APPLEDISPLAY is not set
939# CONFIG_USB_LD is not set
940# CONFIG_USB_TRANCEVIBRATOR is not set
941# CONFIG_USB_IOWARRIOR is not set
942# CONFIG_USB_ISIGHTFW is not set
943# CONFIG_USB_VST is not set
944CONFIG_USB_GADGET=y
945# CONFIG_USB_GADGET_DEBUG_FILES is not set
946CONFIG_USB_GADGET_VBUS_DRAW=2
947CONFIG_USB_GADGET_SELECTED=y
948CONFIG_USB_GADGET_AT91=y
949CONFIG_USB_AT91=y
950# CONFIG_USB_GADGET_ATMEL_USBA is not set
951# CONFIG_USB_GADGET_FSL_USB2 is not set
952# CONFIG_USB_GADGET_LH7A40X is not set
953# CONFIG_USB_GADGET_OMAP is not set
954# CONFIG_USB_GADGET_PXA25X is not set
955# CONFIG_USB_GADGET_PXA27X is not set
956# CONFIG_USB_GADGET_S3C_HSOTG is not set
957# CONFIG_USB_GADGET_IMX is not set
958# CONFIG_USB_GADGET_S3C2410 is not set
959# CONFIG_USB_GADGET_M66592 is not set
960# CONFIG_USB_GADGET_AMD5536UDC is not set
961# CONFIG_USB_GADGET_FSL_QE is not set
962# CONFIG_USB_GADGET_CI13XXX is not set
963# CONFIG_USB_GADGET_NET2280 is not set
964# CONFIG_USB_GADGET_GOKU is not set
965# CONFIG_USB_GADGET_LANGWELL is not set
966# CONFIG_USB_GADGET_DUMMY_HCD is not set
967# CONFIG_USB_GADGET_DUALSPEED is not set
968# CONFIG_USB_ZERO is not set
969# CONFIG_USB_AUDIO is not set
970CONFIG_USB_ETH=y
971CONFIG_USB_ETH_RNDIS=y
972# CONFIG_USB_GADGETFS is not set
973# CONFIG_USB_FILE_STORAGE is not set
974# CONFIG_USB_G_SERIAL is not set
975# CONFIG_USB_MIDI_GADGET is not set
976# CONFIG_USB_G_PRINTER is not set
977# CONFIG_USB_CDC_COMPOSITE is not set
978
979#
980# OTG and related infrastructure
981#
982# CONFIG_USB_GPIO_VBUS is not set
983# CONFIG_NOP_USB_XCEIV is not set
984CONFIG_MMC=y
985# CONFIG_MMC_DEBUG is not set
986# CONFIG_MMC_UNSAFE_RESUME is not set
987
988#
989# MMC/SD/SDIO Card Drivers
990#
991CONFIG_MMC_BLOCK=y
992CONFIG_MMC_BLOCK_BOUNCE=y
993# CONFIG_SDIO_UART is not set
994# CONFIG_MMC_TEST is not set
995
996#
997# MMC/SD/SDIO Host Controller Drivers
998#
999# CONFIG_MMC_SDHCI is not set
1000CONFIG_MMC_AT91=y
1001# CONFIG_MEMSTICK is not set
1002# CONFIG_ACCESSIBILITY is not set
1003CONFIG_NEW_LEDS=y
1004CONFIG_LEDS_CLASS=y
1005
1006#
1007# LED drivers
1008#
1009# CONFIG_LEDS_PCA9532 is not set
1010CONFIG_LEDS_GPIO=y
1011CONFIG_LEDS_GPIO_PLATFORM=y
1012# CONFIG_LEDS_LP3944 is not set
1013# CONFIG_LEDS_PCA955X is not set
1014# CONFIG_LEDS_BD2802 is not set
1015
1016#
1017# LED Triggers
1018#
1019CONFIG_LEDS_TRIGGERS=y
1020CONFIG_LEDS_TRIGGER_TIMER=y
1021CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1022# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
1023CONFIG_LEDS_TRIGGER_GPIO=y
1024CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
1025
1026#
1027# iptables trigger is under Netfilter config (LED target)
1028#
1029CONFIG_RTC_LIB=y
1030CONFIG_RTC_CLASS=y
1031# CONFIG_RTC_HCTOSYS is not set
1032# CONFIG_RTC_DEBUG is not set
1033
1034#
1035# RTC interfaces
1036#
1037CONFIG_RTC_INTF_SYSFS=y
1038CONFIG_RTC_INTF_PROC=y
1039CONFIG_RTC_INTF_DEV=y
1040# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1041# CONFIG_RTC_DRV_TEST is not set
1042
1043#
1044# I2C RTC drivers
1045#
1046CONFIG_RTC_DRV_DS1307=y
1047# CONFIG_RTC_DRV_DS1374 is not set
1048# CONFIG_RTC_DRV_DS1672 is not set
1049# CONFIG_RTC_DRV_MAX6900 is not set
1050# CONFIG_RTC_DRV_RS5C372 is not set
1051# CONFIG_RTC_DRV_ISL1208 is not set
1052# CONFIG_RTC_DRV_X1205 is not set
1053CONFIG_RTC_DRV_PCF8563=y
1054# CONFIG_RTC_DRV_PCF8583 is not set
1055# CONFIG_RTC_DRV_M41T80 is not set
1056# CONFIG_RTC_DRV_S35390A is not set
1057# CONFIG_RTC_DRV_FM3130 is not set
1058# CONFIG_RTC_DRV_RX8581 is not set
1059# CONFIG_RTC_DRV_RX8025 is not set
1060
1061#
1062# SPI RTC drivers
1063#
1064
1065#
1066# Platform RTC drivers
1067#
1068# CONFIG_RTC_DRV_CMOS is not set
1069# CONFIG_RTC_DRV_DS1286 is not set
1070# CONFIG_RTC_DRV_DS1511 is not set
1071# CONFIG_RTC_DRV_DS1553 is not set
1072# CONFIG_RTC_DRV_DS1742 is not set
1073# CONFIG_RTC_DRV_STK17TA8 is not set
1074# CONFIG_RTC_DRV_M48T86 is not set
1075# CONFIG_RTC_DRV_M48T35 is not set
1076# CONFIG_RTC_DRV_M48T59 is not set
1077# CONFIG_RTC_DRV_BQ4802 is not set
1078# CONFIG_RTC_DRV_V3020 is not set
1079
1080#
1081# on-CPU RTC drivers
1082#
1083# CONFIG_RTC_DRV_AT91RM9200 is not set
1084# CONFIG_DMADEVICES is not set
1085# CONFIG_AUXDISPLAY is not set
1086# CONFIG_REGULATOR is not set
1087# CONFIG_UIO is not set
1088# CONFIG_STAGING is not set
1089
1090#
1091# File systems
1092#
1093CONFIG_EXT2_FS=y
1094# CONFIG_EXT2_FS_XATTR is not set
1095# CONFIG_EXT2_FS_XIP is not set
1096CONFIG_EXT3_FS=y
1097# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
1098# CONFIG_EXT3_FS_XATTR is not set
1099# CONFIG_EXT4_FS is not set
1100CONFIG_JBD=y
1101# CONFIG_REISERFS_FS is not set
1102# CONFIG_JFS_FS is not set
1103# CONFIG_FS_POSIX_ACL is not set
1104# CONFIG_XFS_FS is not set
1105# CONFIG_GFS2_FS is not set
1106# CONFIG_OCFS2_FS is not set
1107# CONFIG_BTRFS_FS is not set
1108CONFIG_FILE_LOCKING=y
1109CONFIG_FSNOTIFY=y
1110CONFIG_DNOTIFY=y
1111CONFIG_INOTIFY=y
1112CONFIG_INOTIFY_USER=y
1113# CONFIG_QUOTA is not set
1114# CONFIG_AUTOFS_FS is not set
1115CONFIG_AUTOFS4_FS=y
1116# CONFIG_FUSE_FS is not set
1117
1118#
1119# Caches
1120#
1121# CONFIG_FSCACHE is not set
1122
1123#
1124# CD-ROM/DVD Filesystems
1125#
1126# CONFIG_ISO9660_FS is not set
1127# CONFIG_UDF_FS is not set
1128
1129#
1130# DOS/FAT/NT Filesystems
1131#
1132CONFIG_FAT_FS=y
1133CONFIG_MSDOS_FS=y
1134CONFIG_VFAT_FS=y
1135CONFIG_FAT_DEFAULT_CODEPAGE=437
1136CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1137# CONFIG_NTFS_FS is not set
1138
1139#
1140# Pseudo filesystems
1141#
1142CONFIG_PROC_FS=y
1143CONFIG_PROC_SYSCTL=y
1144CONFIG_PROC_PAGE_MONITOR=y
1145CONFIG_SYSFS=y
1146CONFIG_TMPFS=y
1147# CONFIG_TMPFS_POSIX_ACL is not set
1148# CONFIG_HUGETLB_PAGE is not set
1149# CONFIG_CONFIGFS_FS is not set
1150CONFIG_MISC_FILESYSTEMS=y
1151# CONFIG_ADFS_FS is not set
1152# CONFIG_AFFS_FS is not set
1153# CONFIG_HFS_FS is not set
1154# CONFIG_HFSPLUS_FS is not set
1155# CONFIG_BEFS_FS is not set
1156# CONFIG_BFS_FS is not set
1157# CONFIG_EFS_FS is not set
1158CONFIG_JFFS2_FS=y
1159CONFIG_JFFS2_FS_DEBUG=0
1160CONFIG_JFFS2_FS_WRITEBUFFER=y
1161# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1162CONFIG_JFFS2_SUMMARY=y
1163# CONFIG_JFFS2_FS_XATTR is not set
1164# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1165CONFIG_JFFS2_ZLIB=y
1166# CONFIG_JFFS2_LZO is not set
1167CONFIG_JFFS2_RTIME=y
1168# CONFIG_JFFS2_RUBIN is not set
1169CONFIG_CRAMFS=y
1170# CONFIG_SQUASHFS is not set
1171# CONFIG_VXFS_FS is not set
1172CONFIG_MINIX_FS=y
1173# CONFIG_OMFS_FS is not set
1174# CONFIG_HPFS_FS is not set
1175# CONFIG_QNX4FS_FS is not set
1176# CONFIG_ROMFS_FS is not set
1177# CONFIG_SYSV_FS is not set
1178# CONFIG_UFS_FS is not set
1179# CONFIG_NILFS2_FS is not set
1180CONFIG_NETWORK_FILESYSTEMS=y
1181CONFIG_NFS_FS=y
1182CONFIG_NFS_V3=y
1183# CONFIG_NFS_V3_ACL is not set
1184# CONFIG_NFS_V4 is not set
1185CONFIG_ROOT_NFS=y
1186# CONFIG_NFSD is not set
1187CONFIG_LOCKD=y
1188CONFIG_LOCKD_V4=y
1189CONFIG_NFS_COMMON=y
1190CONFIG_SUNRPC=y
1191# CONFIG_RPCSEC_GSS_KRB5 is not set
1192# CONFIG_RPCSEC_GSS_SPKM3 is not set
1193# CONFIG_SMB_FS is not set
1194# CONFIG_CIFS is not set
1195# CONFIG_NCP_FS is not set
1196# CONFIG_CODA_FS is not set
1197# CONFIG_AFS_FS is not set
1198
1199#
1200# Partition Types
1201#
1202CONFIG_PARTITION_ADVANCED=y
1203# CONFIG_ACORN_PARTITION is not set
1204# CONFIG_OSF_PARTITION is not set
1205# CONFIG_AMIGA_PARTITION is not set
1206# CONFIG_ATARI_PARTITION is not set
1207# CONFIG_MAC_PARTITION is not set
1208CONFIG_MSDOS_PARTITION=y
1209# CONFIG_BSD_DISKLABEL is not set
1210# CONFIG_MINIX_SUBPARTITION is not set
1211# CONFIG_SOLARIS_X86_PARTITION is not set
1212# CONFIG_UNIXWARE_DISKLABEL is not set
1213# CONFIG_LDM_PARTITION is not set
1214# CONFIG_SGI_PARTITION is not set
1215# CONFIG_ULTRIX_PARTITION is not set
1216# CONFIG_SUN_PARTITION is not set
1217# CONFIG_KARMA_PARTITION is not set
1218# CONFIG_EFI_PARTITION is not set
1219# CONFIG_SYSV68_PARTITION is not set
1220CONFIG_NLS=y
1221CONFIG_NLS_DEFAULT="iso8859-1"
1222CONFIG_NLS_CODEPAGE_437=y
1223# CONFIG_NLS_CODEPAGE_737 is not set
1224# CONFIG_NLS_CODEPAGE_775 is not set
1225# CONFIG_NLS_CODEPAGE_850 is not set
1226# CONFIG_NLS_CODEPAGE_852 is not set
1227# CONFIG_NLS_CODEPAGE_855 is not set
1228# CONFIG_NLS_CODEPAGE_857 is not set
1229# CONFIG_NLS_CODEPAGE_860 is not set
1230# CONFIG_NLS_CODEPAGE_861 is not set
1231# CONFIG_NLS_CODEPAGE_862 is not set
1232# CONFIG_NLS_CODEPAGE_863 is not set
1233# CONFIG_NLS_CODEPAGE_864 is not set
1234# CONFIG_NLS_CODEPAGE_865 is not set
1235# CONFIG_NLS_CODEPAGE_866 is not set
1236# CONFIG_NLS_CODEPAGE_869 is not set
1237# CONFIG_NLS_CODEPAGE_936 is not set
1238# CONFIG_NLS_CODEPAGE_950 is not set
1239# CONFIG_NLS_CODEPAGE_932 is not set
1240# CONFIG_NLS_CODEPAGE_949 is not set
1241# CONFIG_NLS_CODEPAGE_874 is not set
1242# CONFIG_NLS_ISO8859_8 is not set
1243# CONFIG_NLS_CODEPAGE_1250 is not set
1244# CONFIG_NLS_CODEPAGE_1251 is not set
1245# CONFIG_NLS_ASCII is not set
1246CONFIG_NLS_ISO8859_1=y
1247# CONFIG_NLS_ISO8859_2 is not set
1248# CONFIG_NLS_ISO8859_3 is not set
1249# CONFIG_NLS_ISO8859_4 is not set
1250# CONFIG_NLS_ISO8859_5 is not set
1251# CONFIG_NLS_ISO8859_6 is not set
1252# CONFIG_NLS_ISO8859_7 is not set
1253# CONFIG_NLS_ISO8859_9 is not set
1254# CONFIG_NLS_ISO8859_13 is not set
1255# CONFIG_NLS_ISO8859_14 is not set
1256# CONFIG_NLS_ISO8859_15 is not set
1257# CONFIG_NLS_KOI8_R is not set
1258# CONFIG_NLS_KOI8_U is not set
1259CONFIG_NLS_UTF8=y
1260# CONFIG_DLM is not set
1261
1262#
1263# Kernel hacking
1264#
1265# CONFIG_PRINTK_TIME is not set
1266CONFIG_ENABLE_WARN_DEPRECATED=y
1267CONFIG_ENABLE_MUST_CHECK=y
1268CONFIG_FRAME_WARN=1024
1269# CONFIG_MAGIC_SYSRQ is not set
1270# CONFIG_UNUSED_SYMBOLS is not set
1271# CONFIG_DEBUG_FS is not set
1272# CONFIG_HEADERS_CHECK is not set
1273# CONFIG_DEBUG_KERNEL is not set
1274# CONFIG_SLUB_DEBUG_ON is not set
1275# CONFIG_SLUB_STATS is not set
1276CONFIG_DEBUG_BUGVERBOSE=y
1277CONFIG_DEBUG_MEMORY_INIT=y
1278CONFIG_FRAME_POINTER=y
1279# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1280# CONFIG_LATENCYTOP is not set
1281# CONFIG_SYSCTL_SYSCALL_CHECK is not set
1282CONFIG_HAVE_FUNCTION_TRACER=y
1283CONFIG_TRACING_SUPPORT=y
1284# CONFIG_FTRACE is not set
1285# CONFIG_SAMPLES is not set
1286CONFIG_HAVE_ARCH_KGDB=y
1287# CONFIG_DEBUG_USER is not set
1288
1289#
1290# Security options
1291#
1292# CONFIG_KEYS is not set
1293# CONFIG_SECURITY is not set
1294# CONFIG_SECURITYFS is not set
1295# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1296# CONFIG_CRYPTO is not set
1297# CONFIG_BINARY_PRINTF is not set
1298
1299#
1300# Library routines
1301#
1302CONFIG_BITREVERSE=y
1303CONFIG_GENERIC_FIND_LAST_BIT=y
1304CONFIG_CRC_CCITT=y
1305# CONFIG_CRC16 is not set
1306# CONFIG_CRC_T10DIF is not set
1307# CONFIG_CRC_ITU_T is not set
1308CONFIG_CRC32=y
1309# CONFIG_CRC7 is not set
1310# CONFIG_LIBCRC32C is not set
1311CONFIG_ZLIB_INFLATE=y
1312CONFIG_ZLIB_DEFLATE=y
1313CONFIG_HAS_IOMEM=y
1314CONFIG_HAS_IOPORT=y
1315CONFIG_HAS_DMA=y
1316CONFIG_NLATTR=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index f3074e49f2fa..df9bfbea8612 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc6 3# Linux kernel version: 2.6.31-rc6
4# Tue Sep 16 18:56:58 2008 4# Fri Aug 21 15:41:39 2009
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y 9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y 10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y 11CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y 12CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y 13CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_HAVE_LATENCYTOP_SUPPORT=y 14CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,16 +17,14 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
18CONFIG_HARDIRQS_SW_RESEND=y 17CONFIG_HARDIRQS_SW_RESEND=y
19CONFIG_GENERIC_IRQ_PROBE=y 18CONFIG_GENERIC_IRQ_PROBE=y
20CONFIG_RWSEM_GENERIC_SPINLOCK=y 19CONFIG_RWSEM_GENERIC_SPINLOCK=y
21# CONFIG_ARCH_HAS_ILOG2_U32 is not set
22# CONFIG_ARCH_HAS_ILOG2_U64 is not set
23CONFIG_GENERIC_HWEIGHT=y 20CONFIG_GENERIC_HWEIGHT=y
24CONFIG_GENERIC_CALIBRATE_DELAY=y 21CONFIG_GENERIC_CALIBRATE_DELAY=y
25CONFIG_ARCH_SUPPORTS_AOUT=y
26CONFIG_ZONE_DMA=y 22CONFIG_ZONE_DMA=y
27CONFIG_ARCH_MTD_XIP=y 23CONFIG_ARCH_MTD_XIP=y
28CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y 24CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
29CONFIG_VECTORS_BASE=0xffff0000 25CONFIG_VECTORS_BASE=0xffff0000
30CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
27CONFIG_CONSTRUCTORS=y
31 28
32# 29#
33# General setup 30# General setup
@@ -44,10 +41,19 @@ CONFIG_SYSVIPC_SYSCTL=y
44# CONFIG_BSD_PROCESS_ACCT is not set 41# CONFIG_BSD_PROCESS_ACCT is not set
45# CONFIG_TASKSTATS is not set 42# CONFIG_TASKSTATS is not set
46# CONFIG_AUDIT is not set 43# CONFIG_AUDIT is not set
44
45#
46# RCU Subsystem
47#
48CONFIG_CLASSIC_RCU=y
49# CONFIG_TREE_RCU is not set
50# CONFIG_PREEMPT_RCU is not set
51# CONFIG_TREE_RCU_TRACE is not set
52# CONFIG_PREEMPT_RCU_TRACE is not set
47# CONFIG_IKCONFIG is not set 53# CONFIG_IKCONFIG is not set
48CONFIG_LOG_BUF_SHIFT=14 54CONFIG_LOG_BUF_SHIFT=14
49# CONFIG_CGROUPS is not set
50# CONFIG_GROUP_SCHED is not set 55# CONFIG_GROUP_SCHED is not set
56# CONFIG_CGROUPS is not set
51CONFIG_SYSFS_DEPRECATED=y 57CONFIG_SYSFS_DEPRECATED=y
52CONFIG_SYSFS_DEPRECATED_V2=y 58CONFIG_SYSFS_DEPRECATED_V2=y
53# CONFIG_RELAY is not set 59# CONFIG_RELAY is not set
@@ -56,9 +62,11 @@ CONFIG_NAMESPACES=y
56# CONFIG_IPC_NS is not set 62# CONFIG_IPC_NS is not set
57# CONFIG_USER_NS is not set 63# CONFIG_USER_NS is not set
58# CONFIG_PID_NS is not set 64# CONFIG_PID_NS is not set
65# CONFIG_NET_NS is not set
59# CONFIG_BLK_DEV_INITRD is not set 66# CONFIG_BLK_DEV_INITRD is not set
60CONFIG_CC_OPTIMIZE_FOR_SIZE=y 67CONFIG_CC_OPTIMIZE_FOR_SIZE=y
61CONFIG_SYSCTL=y 68CONFIG_SYSCTL=y
69CONFIG_ANON_INODES=y
62# CONFIG_EMBEDDED is not set 70# CONFIG_EMBEDDED is not set
63CONFIG_UID16=y 71CONFIG_UID16=y
64CONFIG_SYSCTL_SYSCALL=y 72CONFIG_SYSCTL_SYSCALL=y
@@ -69,17 +77,22 @@ CONFIG_HOTPLUG=y
69CONFIG_PRINTK=y 77CONFIG_PRINTK=y
70CONFIG_BUG=y 78CONFIG_BUG=y
71CONFIG_ELF_CORE=y 79CONFIG_ELF_CORE=y
72CONFIG_COMPAT_BRK=y
73CONFIG_BASE_FULL=y 80CONFIG_BASE_FULL=y
74CONFIG_FUTEX=y 81CONFIG_FUTEX=y
75CONFIG_ANON_INODES=y
76CONFIG_EPOLL=y 82CONFIG_EPOLL=y
77CONFIG_SIGNALFD=y 83CONFIG_SIGNALFD=y
78CONFIG_TIMERFD=y 84CONFIG_TIMERFD=y
79CONFIG_EVENTFD=y 85CONFIG_EVENTFD=y
80CONFIG_SHMEM=y 86CONFIG_SHMEM=y
87CONFIG_AIO=y
88
89#
90# Performance Counters
91#
81CONFIG_VM_EVENT_COUNTERS=y 92CONFIG_VM_EVENT_COUNTERS=y
82CONFIG_SLUB_DEBUG=y 93CONFIG_SLUB_DEBUG=y
94# CONFIG_STRIP_ASM_SYMS is not set
95CONFIG_COMPAT_BRK=y
83# CONFIG_SLAB is not set 96# CONFIG_SLAB is not set
84CONFIG_SLUB=y 97CONFIG_SLUB=y
85# CONFIG_SLOB is not set 98# CONFIG_SLOB is not set
@@ -87,30 +100,25 @@ CONFIG_SLUB=y
87# CONFIG_MARKERS is not set 100# CONFIG_MARKERS is not set
88CONFIG_HAVE_OPROFILE=y 101CONFIG_HAVE_OPROFILE=y
89# CONFIG_KPROBES is not set 102# CONFIG_KPROBES is not set
90# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
91# CONFIG_HAVE_IOREMAP_PROT is not set
92CONFIG_HAVE_KPROBES=y 103CONFIG_HAVE_KPROBES=y
93CONFIG_HAVE_KRETPROBES=y 104CONFIG_HAVE_KRETPROBES=y
94# CONFIG_HAVE_ARCH_TRACEHOOK is not set
95# CONFIG_HAVE_DMA_ATTRS is not set
96# CONFIG_USE_GENERIC_SMP_HELPERS is not set
97CONFIG_HAVE_CLK=y 105CONFIG_HAVE_CLK=y
98CONFIG_PROC_PAGE_MONITOR=y 106
107#
108# GCOV-based kernel profiling
109#
110# CONFIG_SLOW_WORK is not set
99CONFIG_HAVE_GENERIC_DMA_COHERENT=y 111CONFIG_HAVE_GENERIC_DMA_COHERENT=y
100CONFIG_SLABINFO=y 112CONFIG_SLABINFO=y
101CONFIG_RT_MUTEXES=y 113CONFIG_RT_MUTEXES=y
102# CONFIG_TINY_SHMEM is not set
103CONFIG_BASE_SMALL=0 114CONFIG_BASE_SMALL=0
104CONFIG_MODULES=y 115CONFIG_MODULES=y
105# CONFIG_MODULE_FORCE_LOAD is not set 116# CONFIG_MODULE_FORCE_LOAD is not set
106# CONFIG_MODULE_UNLOAD is not set 117# CONFIG_MODULE_UNLOAD is not set
107# CONFIG_MODVERSIONS is not set 118# CONFIG_MODVERSIONS is not set
108# CONFIG_MODULE_SRCVERSION_ALL is not set 119# CONFIG_MODULE_SRCVERSION_ALL is not set
109CONFIG_KMOD=y
110CONFIG_BLOCK=y 120CONFIG_BLOCK=y
111# CONFIG_LBD is not set 121CONFIG_LBDAF=y
112# CONFIG_BLK_DEV_IO_TRACE is not set
113# CONFIG_LSF is not set
114# CONFIG_BLK_DEV_BSG is not set 122# CONFIG_BLK_DEV_BSG is not set
115# CONFIG_BLK_DEV_INTEGRITY is not set 123# CONFIG_BLK_DEV_INTEGRITY is not set
116 124
@@ -126,7 +134,7 @@ CONFIG_IOSCHED_CFQ=y
126CONFIG_DEFAULT_CFQ=y 134CONFIG_DEFAULT_CFQ=y
127# CONFIG_DEFAULT_NOOP is not set 135# CONFIG_DEFAULT_NOOP is not set
128CONFIG_DEFAULT_IOSCHED="cfq" 136CONFIG_DEFAULT_IOSCHED="cfq"
129CONFIG_CLASSIC_RCU=y 137CONFIG_FREEZER=y
130 138
131# 139#
132# System Type 140# System Type
@@ -136,14 +144,15 @@ CONFIG_CLASSIC_RCU=y
136# CONFIG_ARCH_REALVIEW is not set 144# CONFIG_ARCH_REALVIEW is not set
137# CONFIG_ARCH_VERSATILE is not set 145# CONFIG_ARCH_VERSATILE is not set
138# CONFIG_ARCH_AT91 is not set 146# CONFIG_ARCH_AT91 is not set
139# CONFIG_ARCH_CLPS7500 is not set
140# CONFIG_ARCH_CLPS711X is not set 147# CONFIG_ARCH_CLPS711X is not set
148# CONFIG_ARCH_GEMINI is not set
141# CONFIG_ARCH_EBSA110 is not set 149# CONFIG_ARCH_EBSA110 is not set
142# CONFIG_ARCH_EP93XX is not set 150# CONFIG_ARCH_EP93XX is not set
143# CONFIG_ARCH_FOOTBRIDGE is not set 151# CONFIG_ARCH_FOOTBRIDGE is not set
152# CONFIG_ARCH_MXC is not set
153# CONFIG_ARCH_STMP3XXX is not set
144# CONFIG_ARCH_NETX is not set 154# CONFIG_ARCH_NETX is not set
145# CONFIG_ARCH_H720X is not set 155# CONFIG_ARCH_H720X is not set
146# CONFIG_ARCH_IMX is not set
147# CONFIG_ARCH_IOP13XX is not set 156# CONFIG_ARCH_IOP13XX is not set
148# CONFIG_ARCH_IOP32X is not set 157# CONFIG_ARCH_IOP32X is not set
149# CONFIG_ARCH_IOP33X is not set 158# CONFIG_ARCH_IOP33X is not set
@@ -152,23 +161,25 @@ CONFIG_CLASSIC_RCU=y
152# CONFIG_ARCH_IXP4XX is not set 161# CONFIG_ARCH_IXP4XX is not set
153# CONFIG_ARCH_L7200 is not set 162# CONFIG_ARCH_L7200 is not set
154# CONFIG_ARCH_KIRKWOOD is not set 163# CONFIG_ARCH_KIRKWOOD is not set
155# CONFIG_ARCH_KS8695 is not set
156# CONFIG_ARCH_NS9XXX is not set
157# CONFIG_ARCH_LOKI is not set 164# CONFIG_ARCH_LOKI is not set
158# CONFIG_ARCH_MV78XX0 is not set 165# CONFIG_ARCH_MV78XX0 is not set
159# CONFIG_ARCH_MXC is not set
160# CONFIG_ARCH_ORION5X is not set 166# CONFIG_ARCH_ORION5X is not set
167# CONFIG_ARCH_MMP is not set
168# CONFIG_ARCH_KS8695 is not set
169# CONFIG_ARCH_NS9XXX is not set
170# CONFIG_ARCH_W90X900 is not set
161# CONFIG_ARCH_PNX4008 is not set 171# CONFIG_ARCH_PNX4008 is not set
162# CONFIG_ARCH_PXA is not set 172# CONFIG_ARCH_PXA is not set
173# CONFIG_ARCH_MSM is not set
163# CONFIG_ARCH_RPC is not set 174# CONFIG_ARCH_RPC is not set
164CONFIG_ARCH_SA1100=y 175CONFIG_ARCH_SA1100=y
165# CONFIG_ARCH_S3C2410 is not set 176# CONFIG_ARCH_S3C2410 is not set
177# CONFIG_ARCH_S3C64XX is not set
166# CONFIG_ARCH_SHARK is not set 178# CONFIG_ARCH_SHARK is not set
167# CONFIG_ARCH_LH7A40X is not set 179# CONFIG_ARCH_LH7A40X is not set
180# CONFIG_ARCH_U300 is not set
168# CONFIG_ARCH_DAVINCI is not set 181# CONFIG_ARCH_DAVINCI is not set
169# CONFIG_ARCH_OMAP is not set 182# CONFIG_ARCH_OMAP is not set
170# CONFIG_ARCH_MSM7X00A is not set
171CONFIG_DMABOUNCE=y
172 183
173# 184#
174# SA11x0 Implementations 185# SA11x0 Implementations
@@ -189,14 +200,6 @@ CONFIG_SA1100_JORNADA720_SSP=y
189CONFIG_SA1100_SSP=y 200CONFIG_SA1100_SSP=y
190 201
191# 202#
192# Boot options
193#
194
195#
196# Power management
197#
198
199#
200# Processor Type 203# Processor Type
201# 204#
202CONFIG_CPU_32=y 205CONFIG_CPU_32=y
@@ -215,8 +218,8 @@ CONFIG_CPU_CP15_MMU=y
215# 218#
216# CONFIG_CPU_ICACHE_DISABLE is not set 219# CONFIG_CPU_ICACHE_DISABLE is not set
217# CONFIG_CPU_DCACHE_DISABLE is not set 220# CONFIG_CPU_DCACHE_DISABLE is not set
218# CONFIG_OUTER_CACHE is not set
219CONFIG_SA1111=y 221CONFIG_SA1111=y
222CONFIG_DMABOUNCE=y
220CONFIG_FORCE_MAX_ZONEORDER=9 223CONFIG_FORCE_MAX_ZONEORDER=9
221 224
222# 225#
@@ -246,30 +249,36 @@ CONFIG_TICK_ONESHOT=y
246# CONFIG_NO_HZ is not set 249# CONFIG_NO_HZ is not set
247# CONFIG_HIGH_RES_TIMERS is not set 250# CONFIG_HIGH_RES_TIMERS is not set
248CONFIG_GENERIC_CLOCKEVENTS_BUILD=y 251CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
252CONFIG_VMSPLIT_3G=y
253# CONFIG_VMSPLIT_2G is not set
254# CONFIG_VMSPLIT_1G is not set
255CONFIG_PAGE_OFFSET=0xC0000000
249# CONFIG_PREEMPT is not set 256# CONFIG_PREEMPT is not set
250CONFIG_HZ=100 257CONFIG_HZ=100
251# CONFIG_AEABI is not set 258# CONFIG_AEABI is not set
252CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
253CONFIG_ARCH_SPARSEMEM_ENABLE=y 259CONFIG_ARCH_SPARSEMEM_ENABLE=y
254CONFIG_ARCH_SELECT_MEMORY_MODEL=y 260CONFIG_ARCH_SPARSEMEM_DEFAULT=y
255CONFIG_NODES_SHIFT=2 261# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
262# CONFIG_HIGHMEM is not set
256CONFIG_SELECT_MEMORY_MODEL=y 263CONFIG_SELECT_MEMORY_MODEL=y
257# CONFIG_FLATMEM_MANUAL is not set 264# CONFIG_FLATMEM_MANUAL is not set
258CONFIG_DISCONTIGMEM_MANUAL=y 265# CONFIG_DISCONTIGMEM_MANUAL is not set
259# CONFIG_SPARSEMEM_MANUAL is not set 266CONFIG_SPARSEMEM_MANUAL=y
260CONFIG_DISCONTIGMEM=y 267CONFIG_SPARSEMEM=y
261CONFIG_FLAT_NODE_MEM_MAP=y 268CONFIG_HAVE_MEMORY_PRESENT=y
262CONFIG_NEED_MULTIPLE_NODES=y 269CONFIG_SPARSEMEM_EXTREME=y
263# CONFIG_SPARSEMEM_STATIC is not set
264# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
265CONFIG_PAGEFLAGS_EXTENDED=y 270CONFIG_PAGEFLAGS_EXTENDED=y
266CONFIG_SPLIT_PTLOCK_CPUS=4096 271CONFIG_SPLIT_PTLOCK_CPUS=4096
267# CONFIG_RESOURCES_64BIT is not set 272# CONFIG_PHYS_ADDR_T_64BIT is not set
268CONFIG_ZONE_DMA_FLAG=1 273CONFIG_ZONE_DMA_FLAG=1
269CONFIG_BOUNCE=y 274CONFIG_BOUNCE=y
270CONFIG_VIRT_TO_BUS=y 275CONFIG_VIRT_TO_BUS=y
276CONFIG_HAVE_MLOCK=y
277CONFIG_HAVE_MLOCKED_PAGE_BIT=y
278CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
271# CONFIG_LEDS is not set 279# CONFIG_LEDS is not set
272CONFIG_ALIGNMENT_TRAP=y 280CONFIG_ALIGNMENT_TRAP=y
281# CONFIG_UACCESS_WITH_MEMCPY is not set
273 282
274# 283#
275# Boot options 284# Boot options
@@ -281,9 +290,10 @@ CONFIG_CMDLINE=""
281# CONFIG_KEXEC is not set 290# CONFIG_KEXEC is not set
282 291
283# 292#
284# CPU Frequency scaling 293# CPU Power Management
285# 294#
286# CONFIG_CPU_FREQ is not set 295# CONFIG_CPU_FREQ is not set
296# CONFIG_CPU_IDLE is not set
287 297
288# 298#
289# Floating point emulation 299# Floating point emulation
@@ -294,12 +304,14 @@ CONFIG_CMDLINE=""
294# 304#
295CONFIG_FPE_NWFPE=y 305CONFIG_FPE_NWFPE=y
296# CONFIG_FPE_NWFPE_XP is not set 306# CONFIG_FPE_NWFPE_XP is not set
297CONFIG_FPE_FASTFPE=y 307# CONFIG_FPE_FASTFPE is not set
298 308
299# 309#
300# Userspace binary formats 310# Userspace binary formats
301# 311#
302CONFIG_BINFMT_ELF=y 312CONFIG_BINFMT_ELF=y
313# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
314CONFIG_HAVE_AOUT=y
303CONFIG_BINFMT_AOUT=y 315CONFIG_BINFMT_AOUT=y
304# CONFIG_BINFMT_MISC is not set 316# CONFIG_BINFMT_MISC is not set
305# CONFIG_ARTHUR is not set 317# CONFIG_ARTHUR is not set
@@ -353,7 +365,6 @@ CONFIG_INET_TCP_DIAG=y
353CONFIG_TCP_CONG_CUBIC=y 365CONFIG_TCP_CONG_CUBIC=y
354CONFIG_DEFAULT_TCP_CONG="cubic" 366CONFIG_DEFAULT_TCP_CONG="cubic"
355# CONFIG_TCP_MD5SIG is not set 367# CONFIG_TCP_MD5SIG is not set
356# CONFIG_IP_VS is not set
357# CONFIG_IPV6 is not set 368# CONFIG_IPV6 is not set
358# CONFIG_NETWORK_SECMARK is not set 369# CONFIG_NETWORK_SECMARK is not set
359CONFIG_NETFILTER=y 370CONFIG_NETFILTER=y
@@ -367,10 +378,12 @@ CONFIG_NETFILTER_ADVANCED=y
367# CONFIG_NETFILTER_NETLINK_LOG is not set 378# CONFIG_NETFILTER_NETLINK_LOG is not set
368# CONFIG_NF_CONNTRACK is not set 379# CONFIG_NF_CONNTRACK is not set
369# CONFIG_NETFILTER_XTABLES is not set 380# CONFIG_NETFILTER_XTABLES is not set
381# CONFIG_IP_VS is not set
370 382
371# 383#
372# IP: Netfilter Configuration 384# IP: Netfilter Configuration
373# 385#
386# CONFIG_NF_DEFRAG_IPV4 is not set
374# CONFIG_IP_NF_QUEUE is not set 387# CONFIG_IP_NF_QUEUE is not set
375# CONFIG_IP_NF_IPTABLES is not set 388# CONFIG_IP_NF_IPTABLES is not set
376# CONFIG_IP_NF_ARPTABLES is not set 389# CONFIG_IP_NF_ARPTABLES is not set
@@ -379,6 +392,7 @@ CONFIG_NETFILTER_ADVANCED=y
379# CONFIG_TIPC is not set 392# CONFIG_TIPC is not set
380# CONFIG_ATM is not set 393# CONFIG_ATM is not set
381# CONFIG_BRIDGE is not set 394# CONFIG_BRIDGE is not set
395# CONFIG_NET_DSA is not set
382# CONFIG_VLAN_8021Q is not set 396# CONFIG_VLAN_8021Q is not set
383# CONFIG_DECNET is not set 397# CONFIG_DECNET is not set
384# CONFIG_LLC2 is not set 398# CONFIG_LLC2 is not set
@@ -388,7 +402,10 @@ CONFIG_NETFILTER_ADVANCED=y
388# CONFIG_LAPB is not set 402# CONFIG_LAPB is not set
389# CONFIG_ECONET is not set 403# CONFIG_ECONET is not set
390# CONFIG_WAN_ROUTER is not set 404# CONFIG_WAN_ROUTER is not set
405# CONFIG_PHONET is not set
406# CONFIG_IEEE802154 is not set
391# CONFIG_NET_SCHED is not set 407# CONFIG_NET_SCHED is not set
408# CONFIG_DCB is not set
392 409
393# 410#
394# Network testing 411# Network testing
@@ -431,14 +448,17 @@ CONFIG_IRCOMM=m
431CONFIG_SA1100_FIR=m 448CONFIG_SA1100_FIR=m
432# CONFIG_BT is not set 449# CONFIG_BT is not set
433# CONFIG_AF_RXRPC is not set 450# CONFIG_AF_RXRPC is not set
451CONFIG_WIRELESS=y
452# CONFIG_CFG80211 is not set
453# CONFIG_WIRELESS_OLD_REGULATORY is not set
454# CONFIG_WIRELESS_EXT is not set
455# CONFIG_LIB80211 is not set
434 456
435# 457#
436# Wireless 458# CFG80211 needs to be enabled for MAC80211
437# 459#
438# CONFIG_CFG80211 is not set 460CONFIG_MAC80211_DEFAULT_PS_VALUE=0
439# CONFIG_WIRELESS_EXT is not set 461# CONFIG_WIMAX is not set
440# CONFIG_MAC80211 is not set
441# CONFIG_IEEE80211 is not set
442# CONFIG_RFKILL is not set 462# CONFIG_RFKILL is not set
443# CONFIG_NET_9P is not set 463# CONFIG_NET_9P is not set
444 464
@@ -464,29 +484,34 @@ CONFIG_EXTRA_FIRMWARE=""
464# CONFIG_PNP is not set 484# CONFIG_PNP is not set
465CONFIG_BLK_DEV=y 485CONFIG_BLK_DEV=y
466# CONFIG_BLK_DEV_COW_COMMON is not set 486# CONFIG_BLK_DEV_COW_COMMON is not set
467CONFIG_BLK_DEV_LOOP=m 487CONFIG_BLK_DEV_LOOP=y
468# CONFIG_BLK_DEV_CRYPTOLOOP is not set 488# CONFIG_BLK_DEV_CRYPTOLOOP is not set
469CONFIG_BLK_DEV_NBD=m 489CONFIG_BLK_DEV_NBD=y
470# CONFIG_BLK_DEV_RAM is not set 490# CONFIG_BLK_DEV_RAM is not set
471# CONFIG_CDROM_PKTCDVD is not set 491# CONFIG_CDROM_PKTCDVD is not set
472# CONFIG_ATA_OVER_ETH is not set 492# CONFIG_ATA_OVER_ETH is not set
493# CONFIG_MG_DISK is not set
473CONFIG_MISC_DEVICES=y 494CONFIG_MISC_DEVICES=y
474# CONFIG_EEPROM_93CX6 is not set
475# CONFIG_ENCLOSURE_SERVICES is not set 495# CONFIG_ENCLOSURE_SERVICES is not set
496# CONFIG_C2PORT is not set
497
498#
499# EEPROM support
500#
501# CONFIG_EEPROM_93CX6 is not set
476CONFIG_HAVE_IDE=y 502CONFIG_HAVE_IDE=y
477CONFIG_IDE=y 503CONFIG_IDE=y
478CONFIG_BLK_DEV_IDE=y
479 504
480# 505#
481# Please see Documentation/ide/ide.txt for help/info on IDE drives 506# Please see Documentation/ide/ide.txt for help/info on IDE drives
482# 507#
483# CONFIG_BLK_DEV_IDE_SATA is not set 508# CONFIG_BLK_DEV_IDE_SATA is not set
484CONFIG_BLK_DEV_IDEDISK=y 509CONFIG_IDE_GD=y
485# CONFIG_IDEDISK_MULTI_MODE is not set 510CONFIG_IDE_GD_ATA=y
511# CONFIG_IDE_GD_ATAPI is not set
486CONFIG_BLK_DEV_IDECS=y 512CONFIG_BLK_DEV_IDECS=y
487# CONFIG_BLK_DEV_IDECD is not set 513# CONFIG_BLK_DEV_IDECD is not set
488# CONFIG_BLK_DEV_IDETAPE is not set 514# CONFIG_BLK_DEV_IDETAPE is not set
489# CONFIG_BLK_DEV_IDEFLOPPY is not set
490# CONFIG_IDE_TASK_IOCTL is not set 515# CONFIG_IDE_TASK_IOCTL is not set
491CONFIG_IDE_PROC_FS=y 516CONFIG_IDE_PROC_FS=y
492 517
@@ -513,8 +538,34 @@ CONFIG_DUMMY=y
513# CONFIG_TUN is not set 538# CONFIG_TUN is not set
514# CONFIG_VETH is not set 539# CONFIG_VETH is not set
515# CONFIG_ARCNET is not set 540# CONFIG_ARCNET is not set
516# CONFIG_NET_ETHERNET is not set 541# CONFIG_PHYLIB is not set
517CONFIG_MII=m 542CONFIG_NET_ETHERNET=y
543# CONFIG_MII is not set
544# CONFIG_AX88796 is not set
545# CONFIG_NET_VENDOR_3COM is not set
546# CONFIG_NET_VENDOR_SMC is not set
547# CONFIG_SMC91X is not set
548# CONFIG_DM9000 is not set
549# CONFIG_ETHOC is not set
550# CONFIG_SMC911X is not set
551# CONFIG_SMSC911X is not set
552# CONFIG_NET_VENDOR_RACAL is not set
553# CONFIG_DNET is not set
554# CONFIG_AT1700 is not set
555# CONFIG_DEPCA is not set
556# CONFIG_HP100 is not set
557# CONFIG_NET_ISA is not set
558# CONFIG_IBM_NEW_EMAC_ZMII is not set
559# CONFIG_IBM_NEW_EMAC_RGMII is not set
560# CONFIG_IBM_NEW_EMAC_TAH is not set
561# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
562# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
563# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
564# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
565# CONFIG_NET_PCI is not set
566# CONFIG_B44 is not set
567# CONFIG_CS89x0 is not set
568# CONFIG_KS8842 is not set
518# CONFIG_NETDEV_1000 is not set 569# CONFIG_NETDEV_1000 is not set
519# CONFIG_NETDEV_10000 is not set 570# CONFIG_NETDEV_10000 is not set
520# CONFIG_TR is not set 571# CONFIG_TR is not set
@@ -523,17 +574,27 @@ CONFIG_MII=m
523# Wireless LAN 574# Wireless LAN
524# 575#
525# CONFIG_WLAN_PRE80211 is not set 576# CONFIG_WLAN_PRE80211 is not set
526# CONFIG_WLAN_80211 is not set 577CONFIG_WLAN_80211=y
527# CONFIG_IWLWIFI_LEDS is not set 578# CONFIG_PCMCIA_RAYCS is not set
579# CONFIG_LIBERTAS is not set
580# CONFIG_ATMEL is not set
581# CONFIG_AIRO_CS is not set
582# CONFIG_PCMCIA_WL3501 is not set
583# CONFIG_HOSTAP is not set
584# CONFIG_HERMES is not set
585
586#
587# Enable WiMAX (Networking options) to see the WiMAX drivers
588#
528CONFIG_NET_PCMCIA=y 589CONFIG_NET_PCMCIA=y
529CONFIG_PCMCIA_3C589=m 590# CONFIG_PCMCIA_3C589 is not set
530CONFIG_PCMCIA_3C574=m 591# CONFIG_PCMCIA_3C574 is not set
531CONFIG_PCMCIA_FMVJ18X=m 592# CONFIG_PCMCIA_FMVJ18X is not set
532CONFIG_PCMCIA_PCNET=m 593# CONFIG_PCMCIA_PCNET is not set
533CONFIG_PCMCIA_NMCLAN=m 594# CONFIG_PCMCIA_NMCLAN is not set
534CONFIG_PCMCIA_SMC91C92=m 595# CONFIG_PCMCIA_SMC91C92 is not set
535CONFIG_PCMCIA_XIRC2PS=m 596# CONFIG_PCMCIA_XIRC2PS is not set
536CONFIG_PCMCIA_AXNET=m 597# CONFIG_PCMCIA_AXNET is not set
537# CONFIG_WAN is not set 598# CONFIG_WAN is not set
538# CONFIG_PPP is not set 599# CONFIG_PPP is not set
539# CONFIG_SLIP is not set 600# CONFIG_SLIP is not set
@@ -565,20 +626,23 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
565# 626#
566CONFIG_INPUT_KEYBOARD=y 627CONFIG_INPUT_KEYBOARD=y
567# CONFIG_KEYBOARD_ATKBD is not set 628# CONFIG_KEYBOARD_ATKBD is not set
568# CONFIG_KEYBOARD_SUNKBD is not set
569# CONFIG_KEYBOARD_LKKBD is not set 629# CONFIG_KEYBOARD_LKKBD is not set
570# CONFIG_KEYBOARD_XTKBD is not set 630# CONFIG_KEYBOARD_GPIO is not set
631# CONFIG_KEYBOARD_MATRIX is not set
632CONFIG_KEYBOARD_HP7XX=y
571# CONFIG_KEYBOARD_NEWTON is not set 633# CONFIG_KEYBOARD_NEWTON is not set
572# CONFIG_KEYBOARD_STOWAWAY is not set 634# CONFIG_KEYBOARD_STOWAWAY is not set
573CONFIG_KEYBOARD_HP7XX=y 635# CONFIG_KEYBOARD_SUNKBD is not set
574# CONFIG_KEYBOARD_GPIO is not set 636# CONFIG_KEYBOARD_XTKBD is not set
575# CONFIG_INPUT_MOUSE is not set 637# CONFIG_INPUT_MOUSE is not set
576# CONFIG_INPUT_JOYSTICK is not set 638# CONFIG_INPUT_JOYSTICK is not set
577# CONFIG_INPUT_TABLET is not set 639# CONFIG_INPUT_TABLET is not set
578CONFIG_INPUT_TOUCHSCREEN=y 640CONFIG_INPUT_TOUCHSCREEN=y
641# CONFIG_TOUCHSCREEN_AD7879 is not set
579# CONFIG_TOUCHSCREEN_FUJITSU is not set 642# CONFIG_TOUCHSCREEN_FUJITSU is not set
580# CONFIG_TOUCHSCREEN_GUNZE is not set 643# CONFIG_TOUCHSCREEN_GUNZE is not set
581# CONFIG_TOUCHSCREEN_ELO is not set 644# CONFIG_TOUCHSCREEN_ELO is not set
645# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
582# CONFIG_TOUCHSCREEN_MTOUCH is not set 646# CONFIG_TOUCHSCREEN_MTOUCH is not set
583# CONFIG_TOUCHSCREEN_INEXIO is not set 647# CONFIG_TOUCHSCREEN_INEXIO is not set
584# CONFIG_TOUCHSCREEN_MK712 is not set 648# CONFIG_TOUCHSCREEN_MK712 is not set
@@ -587,8 +651,8 @@ CONFIG_TOUCHSCREEN_HP7XX=y
587# CONFIG_TOUCHSCREEN_PENMOUNT is not set 651# CONFIG_TOUCHSCREEN_PENMOUNT is not set
588# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set 652# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
589# CONFIG_TOUCHSCREEN_TOUCHWIN is not set 653# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
590# CONFIG_TOUCHSCREEN_UCB1400 is not set
591# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set 654# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
655# CONFIG_TOUCHSCREEN_W90X900 is not set
592# CONFIG_INPUT_MISC is not set 656# CONFIG_INPUT_MISC is not set
593 657
594# 658#
@@ -624,11 +688,12 @@ CONFIG_SERIAL_SA1100_CONSOLE=y
624CONFIG_SERIAL_CORE=y 688CONFIG_SERIAL_CORE=y
625CONFIG_SERIAL_CORE_CONSOLE=y 689CONFIG_SERIAL_CORE_CONSOLE=y
626CONFIG_UNIX98_PTYS=y 690CONFIG_UNIX98_PTYS=y
691# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
627CONFIG_LEGACY_PTYS=y 692CONFIG_LEGACY_PTYS=y
628CONFIG_LEGACY_PTY_COUNT=32 693CONFIG_LEGACY_PTY_COUNT=32
629# CONFIG_IPMI_HANDLER is not set 694# CONFIG_IPMI_HANDLER is not set
630CONFIG_HW_RANDOM=m 695CONFIG_HW_RANDOM=m
631# CONFIG_NVRAM is not set 696# CONFIG_HW_RANDOM_TIMERIOMEM is not set
632# CONFIG_DTLK is not set 697# CONFIG_DTLK is not set
633# CONFIG_R3964 is not set 698# CONFIG_R3964 is not set
634 699
@@ -650,6 +715,10 @@ CONFIG_GPIOLIB=y
650# CONFIG_GPIO_SYSFS is not set 715# CONFIG_GPIO_SYSFS is not set
651 716
652# 717#
718# Memory mapped GPIO expanders:
719#
720
721#
653# I2C GPIO expanders: 722# I2C GPIO expanders:
654# 723#
655 724
@@ -663,12 +732,14 @@ CONFIG_GPIOLIB=y
663# CONFIG_W1 is not set 732# CONFIG_W1 is not set
664# CONFIG_POWER_SUPPLY is not set 733# CONFIG_POWER_SUPPLY is not set
665# CONFIG_HWMON is not set 734# CONFIG_HWMON is not set
735# CONFIG_THERMAL is not set
736# CONFIG_THERMAL_HWMON is not set
666# CONFIG_WATCHDOG is not set 737# CONFIG_WATCHDOG is not set
738CONFIG_SSB_POSSIBLE=y
667 739
668# 740#
669# Sonics Silicon Backplane 741# Sonics Silicon Backplane
670# 742#
671CONFIG_SSB_POSSIBLE=y
672# CONFIG_SSB is not set 743# CONFIG_SSB is not set
673 744
674# 745#
@@ -676,6 +747,7 @@ CONFIG_SSB_POSSIBLE=y
676# 747#
677# CONFIG_MFD_CORE is not set 748# CONFIG_MFD_CORE is not set
678# CONFIG_MFD_SM501 is not set 749# CONFIG_MFD_SM501 is not set
750# CONFIG_MFD_ASIC3 is not set
679# CONFIG_HTC_EGPIO is not set 751# CONFIG_HTC_EGPIO is not set
680# CONFIG_HTC_PASIC3 is not set 752# CONFIG_HTC_PASIC3 is not set
681# CONFIG_MFD_TMIO is not set 753# CONFIG_MFD_TMIO is not set
@@ -687,22 +759,7 @@ CONFIG_SSB_POSSIBLE=y
687# Multimedia Capabilities Port drivers 759# Multimedia Capabilities Port drivers
688# 760#
689# CONFIG_MCP_SA11X0 is not set 761# CONFIG_MCP_SA11X0 is not set
690 762# CONFIG_MEDIA_SUPPORT is not set
691#
692# Multimedia devices
693#
694
695#
696# Multimedia core support
697#
698# CONFIG_VIDEO_DEV is not set
699# CONFIG_DVB_CORE is not set
700# CONFIG_VIDEO_MEDIA is not set
701
702#
703# Multimedia drivers
704#
705# CONFIG_DAB is not set
706 763
707# 764#
708# Graphics support 765# Graphics support
@@ -712,6 +769,7 @@ CONFIG_SSB_POSSIBLE=y
712CONFIG_FB=y 769CONFIG_FB=y
713# CONFIG_FIRMWARE_EDID is not set 770# CONFIG_FIRMWARE_EDID is not set
714# CONFIG_FB_DDC is not set 771# CONFIG_FB_DDC is not set
772# CONFIG_FB_BOOT_VESA_SUPPORT is not set
715CONFIG_FB_CFB_FILLRECT=y 773CONFIG_FB_CFB_FILLRECT=y
716CONFIG_FB_CFB_COPYAREA=y 774CONFIG_FB_CFB_COPYAREA=y
717CONFIG_FB_CFB_IMAGEBLIT=y 775CONFIG_FB_CFB_IMAGEBLIT=y
@@ -733,7 +791,17 @@ CONFIG_FB_CFB_IMAGEBLIT=y
733# CONFIG_FB_SA1100 is not set 791# CONFIG_FB_SA1100 is not set
734CONFIG_FB_S1D13XXX=y 792CONFIG_FB_S1D13XXX=y
735# CONFIG_FB_VIRTUAL is not set 793# CONFIG_FB_VIRTUAL is not set
736# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 794# CONFIG_FB_METRONOME is not set
795# CONFIG_FB_MB862XX is not set
796# CONFIG_FB_BROADSHEET is not set
797CONFIG_BACKLIGHT_LCD_SUPPORT=y
798CONFIG_LCD_CLASS_DEVICE=y
799# CONFIG_LCD_ILI9320 is not set
800# CONFIG_LCD_PLATFORM is not set
801CONFIG_LCD_HP700=y
802CONFIG_BACKLIGHT_CLASS_DEVICE=y
803# CONFIG_BACKLIGHT_GENERIC is not set
804CONFIG_BACKLIGHT_HP700=y
737 805
738# 806#
739# Display device support 807# Display device support
@@ -757,6 +825,8 @@ CONFIG_FONT_8x16=y
757# CONFIG_HID_SUPPORT is not set 825# CONFIG_HID_SUPPORT is not set
758# CONFIG_USB_SUPPORT is not set 826# CONFIG_USB_SUPPORT is not set
759# CONFIG_MMC is not set 827# CONFIG_MMC is not set
828# CONFIG_MEMSTICK is not set
829# CONFIG_ACCESSIBILITY is not set
760# CONFIG_NEW_LEDS is not set 830# CONFIG_NEW_LEDS is not set
761CONFIG_RTC_LIB=y 831CONFIG_RTC_LIB=y
762CONFIG_RTC_CLASS=y 832CONFIG_RTC_CLASS=y
@@ -781,12 +851,15 @@ CONFIG_RTC_INTF_DEV=y
781# Platform RTC drivers 851# Platform RTC drivers
782# 852#
783# CONFIG_RTC_DRV_CMOS is not set 853# CONFIG_RTC_DRV_CMOS is not set
854# CONFIG_RTC_DRV_DS1286 is not set
784# CONFIG_RTC_DRV_DS1511 is not set 855# CONFIG_RTC_DRV_DS1511 is not set
785# CONFIG_RTC_DRV_DS1553 is not set 856# CONFIG_RTC_DRV_DS1553 is not set
786# CONFIG_RTC_DRV_DS1742 is not set 857# CONFIG_RTC_DRV_DS1742 is not set
787# CONFIG_RTC_DRV_STK17TA8 is not set 858# CONFIG_RTC_DRV_STK17TA8 is not set
788# CONFIG_RTC_DRV_M48T86 is not set 859# CONFIG_RTC_DRV_M48T86 is not set
860# CONFIG_RTC_DRV_M48T35 is not set
789# CONFIG_RTC_DRV_M48T59 is not set 861# CONFIG_RTC_DRV_M48T59 is not set
862# CONFIG_RTC_DRV_BQ4802 is not set
790# CONFIG_RTC_DRV_V3020 is not set 863# CONFIG_RTC_DRV_V3020 is not set
791 864
792# 865#
@@ -794,15 +867,10 @@ CONFIG_RTC_INTF_DEV=y
794# 867#
795CONFIG_RTC_DRV_SA1100=y 868CONFIG_RTC_DRV_SA1100=y
796# CONFIG_DMADEVICES is not set 869# CONFIG_DMADEVICES is not set
797 870# CONFIG_AUXDISPLAY is not set
798#
799# Voltage and Current regulators
800#
801# CONFIG_REGULATOR is not set 871# CONFIG_REGULATOR is not set
802# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
803# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
804# CONFIG_REGULATOR_BQ24022 is not set
805# CONFIG_UIO is not set 872# CONFIG_UIO is not set
873# CONFIG_STAGING is not set
806 874
807# 875#
808# File systems 876# File systems
@@ -811,12 +879,16 @@ CONFIG_EXT2_FS=y
811# CONFIG_EXT2_FS_XATTR is not set 879# CONFIG_EXT2_FS_XATTR is not set
812# CONFIG_EXT2_FS_XIP is not set 880# CONFIG_EXT2_FS_XIP is not set
813# CONFIG_EXT3_FS is not set 881# CONFIG_EXT3_FS is not set
814# CONFIG_EXT4DEV_FS is not set 882# CONFIG_EXT4_FS is not set
815# CONFIG_REISERFS_FS is not set 883# CONFIG_REISERFS_FS is not set
816# CONFIG_JFS_FS is not set 884# CONFIG_JFS_FS is not set
817# CONFIG_FS_POSIX_ACL is not set 885# CONFIG_FS_POSIX_ACL is not set
818# CONFIG_XFS_FS is not set 886# CONFIG_XFS_FS is not set
887# CONFIG_GFS2_FS is not set
819# CONFIG_OCFS2_FS is not set 888# CONFIG_OCFS2_FS is not set
889# CONFIG_BTRFS_FS is not set
890CONFIG_FILE_LOCKING=y
891CONFIG_FSNOTIFY=y
820CONFIG_DNOTIFY=y 892CONFIG_DNOTIFY=y
821CONFIG_INOTIFY=y 893CONFIG_INOTIFY=y
822CONFIG_INOTIFY_USER=y 894CONFIG_INOTIFY_USER=y
@@ -826,6 +898,11 @@ CONFIG_INOTIFY_USER=y
826# CONFIG_FUSE_FS is not set 898# CONFIG_FUSE_FS is not set
827 899
828# 900#
901# Caches
902#
903# CONFIG_FSCACHE is not set
904
905#
829# CD-ROM/DVD Filesystems 906# CD-ROM/DVD Filesystems
830# 907#
831# CONFIG_ISO9660_FS is not set 908# CONFIG_ISO9660_FS is not set
@@ -846,14 +923,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
846# 923#
847CONFIG_PROC_FS=y 924CONFIG_PROC_FS=y
848CONFIG_PROC_SYSCTL=y 925CONFIG_PROC_SYSCTL=y
926CONFIG_PROC_PAGE_MONITOR=y
849CONFIG_SYSFS=y 927CONFIG_SYSFS=y
850# CONFIG_TMPFS is not set 928# CONFIG_TMPFS is not set
851# CONFIG_HUGETLB_PAGE is not set 929# CONFIG_HUGETLB_PAGE is not set
852# CONFIG_CONFIGFS_FS is not set 930# CONFIG_CONFIGFS_FS is not set
853 931CONFIG_MISC_FILESYSTEMS=y
854#
855# Miscellaneous filesystems
856#
857# CONFIG_ADFS_FS is not set 932# CONFIG_ADFS_FS is not set
858# CONFIG_AFFS_FS is not set 933# CONFIG_AFFS_FS is not set
859# CONFIG_HFS_FS is not set 934# CONFIG_HFS_FS is not set
@@ -862,6 +937,7 @@ CONFIG_SYSFS=y
862# CONFIG_BFS_FS is not set 937# CONFIG_BFS_FS is not set
863# CONFIG_EFS_FS is not set 938# CONFIG_EFS_FS is not set
864# CONFIG_CRAMFS is not set 939# CONFIG_CRAMFS is not set
940# CONFIG_SQUASHFS is not set
865# CONFIG_VXFS_FS is not set 941# CONFIG_VXFS_FS is not set
866# CONFIG_MINIX_FS is not set 942# CONFIG_MINIX_FS is not set
867# CONFIG_OMFS_FS is not set 943# CONFIG_OMFS_FS is not set
@@ -870,6 +946,7 @@ CONFIG_SYSFS=y
870# CONFIG_ROMFS_FS is not set 946# CONFIG_ROMFS_FS is not set
871# CONFIG_SYSV_FS is not set 947# CONFIG_SYSV_FS is not set
872# CONFIG_UFS_FS is not set 948# CONFIG_UFS_FS is not set
949# CONFIG_NILFS2_FS is not set
873# CONFIG_NETWORK_FILESYSTEMS is not set 950# CONFIG_NETWORK_FILESYSTEMS is not set
874 951
875# 952#
@@ -935,12 +1012,16 @@ CONFIG_DEBUG_KERNEL=y
935CONFIG_DETECT_SOFTLOCKUP=y 1012CONFIG_DETECT_SOFTLOCKUP=y
936# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set 1013# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
937CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 1014CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
1015CONFIG_DETECT_HUNG_TASK=y
1016# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
1017CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
938CONFIG_SCHED_DEBUG=y 1018CONFIG_SCHED_DEBUG=y
939# CONFIG_SCHEDSTATS is not set 1019# CONFIG_SCHEDSTATS is not set
940# CONFIG_TIMER_STATS is not set 1020# CONFIG_TIMER_STATS is not set
941# CONFIG_DEBUG_OBJECTS is not set 1021# CONFIG_DEBUG_OBJECTS is not set
942# CONFIG_SLUB_DEBUG_ON is not set 1022# CONFIG_SLUB_DEBUG_ON is not set
943# CONFIG_SLUB_STATS is not set 1023# CONFIG_SLUB_STATS is not set
1024# CONFIG_DEBUG_KMEMLEAK is not set
944# CONFIG_DEBUG_RT_MUTEXES is not set 1025# CONFIG_DEBUG_RT_MUTEXES is not set
945# CONFIG_RT_MUTEX_TESTER is not set 1026# CONFIG_RT_MUTEX_TESTER is not set
946# CONFIG_DEBUG_SPINLOCK is not set 1027# CONFIG_DEBUG_SPINLOCK is not set
@@ -958,19 +1039,20 @@ CONFIG_DEBUG_BUGVERBOSE=y
958CONFIG_DEBUG_MEMORY_INIT=y 1039CONFIG_DEBUG_MEMORY_INIT=y
959# CONFIG_DEBUG_LIST is not set 1040# CONFIG_DEBUG_LIST is not set
960# CONFIG_DEBUG_SG is not set 1041# CONFIG_DEBUG_SG is not set
1042# CONFIG_DEBUG_NOTIFIERS is not set
961CONFIG_FRAME_POINTER=y 1043CONFIG_FRAME_POINTER=y
962# CONFIG_BOOT_PRINTK_DELAY is not set 1044# CONFIG_BOOT_PRINTK_DELAY is not set
963# CONFIG_RCU_TORTURE_TEST is not set 1045# CONFIG_RCU_TORTURE_TEST is not set
1046# CONFIG_RCU_CPU_STALL_DETECTOR is not set
964# CONFIG_BACKTRACE_SELF_TEST is not set 1047# CONFIG_BACKTRACE_SELF_TEST is not set
1048# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
965# CONFIG_FAULT_INJECTION is not set 1049# CONFIG_FAULT_INJECTION is not set
966# CONFIG_LATENCYTOP is not set 1050# CONFIG_LATENCYTOP is not set
967# CONFIG_SYSCTL_SYSCALL_CHECK is not set 1051# CONFIG_SYSCTL_SYSCALL_CHECK is not set
968CONFIG_HAVE_FTRACE=y 1052# CONFIG_PAGE_POISONING is not set
969CONFIG_HAVE_DYNAMIC_FTRACE=y 1053CONFIG_HAVE_FUNCTION_TRACER=y
1054CONFIG_TRACING_SUPPORT=y
970# CONFIG_FTRACE is not set 1055# CONFIG_FTRACE is not set
971# CONFIG_IRQSOFF_TRACER is not set
972# CONFIG_SCHED_TRACER is not set
973# CONFIG_CONTEXT_SWITCH_TRACER is not set
974# CONFIG_SAMPLES is not set 1056# CONFIG_SAMPLES is not set
975CONFIG_HAVE_ARCH_KGDB=y 1057CONFIG_HAVE_ARCH_KGDB=y
976# CONFIG_KGDB is not set 1058# CONFIG_KGDB is not set
@@ -985,13 +1067,16 @@ CONFIG_DEBUG_LL=y
985# 1067#
986# CONFIG_KEYS is not set 1068# CONFIG_KEYS is not set
987# CONFIG_SECURITY is not set 1069# CONFIG_SECURITY is not set
1070# CONFIG_SECURITYFS is not set
988# CONFIG_SECURITY_FILE_CAPABILITIES is not set 1071# CONFIG_SECURITY_FILE_CAPABILITIES is not set
989CONFIG_CRYPTO=y 1072CONFIG_CRYPTO=y
990 1073
991# 1074#
992# Crypto core or helper 1075# Crypto core or helper
993# 1076#
1077# CONFIG_CRYPTO_FIPS is not set
994# CONFIG_CRYPTO_MANAGER is not set 1078# CONFIG_CRYPTO_MANAGER is not set
1079# CONFIG_CRYPTO_MANAGER2 is not set
995# CONFIG_CRYPTO_GF128MUL is not set 1080# CONFIG_CRYPTO_GF128MUL is not set
996# CONFIG_CRYPTO_NULL is not set 1081# CONFIG_CRYPTO_NULL is not set
997# CONFIG_CRYPTO_CRYPTD is not set 1082# CONFIG_CRYPTO_CRYPTD is not set
@@ -1062,15 +1147,21 @@ CONFIG_CRYPTO=y
1062# Compression 1147# Compression
1063# 1148#
1064# CONFIG_CRYPTO_DEFLATE is not set 1149# CONFIG_CRYPTO_DEFLATE is not set
1150# CONFIG_CRYPTO_ZLIB is not set
1065# CONFIG_CRYPTO_LZO is not set 1151# CONFIG_CRYPTO_LZO is not set
1152
1153#
1154# Random Number Generation
1155#
1156# CONFIG_CRYPTO_ANSI_CPRNG is not set
1066CONFIG_CRYPTO_HW=y 1157CONFIG_CRYPTO_HW=y
1158# CONFIG_BINARY_PRINTF is not set
1067 1159
1068# 1160#
1069# Library routines 1161# Library routines
1070# 1162#
1071CONFIG_BITREVERSE=y 1163CONFIG_BITREVERSE=y
1072# CONFIG_GENERIC_FIND_FIRST_BIT is not set 1164CONFIG_GENERIC_FIND_LAST_BIT=y
1073# CONFIG_GENERIC_FIND_NEXT_BIT is not set
1074CONFIG_CRC_CCITT=m 1165CONFIG_CRC_CCITT=m
1075# CONFIG_CRC16 is not set 1166# CONFIG_CRC16 is not set
1076# CONFIG_CRC_T10DIF is not set 1167# CONFIG_CRC_T10DIF is not set
@@ -1078,7 +1169,7 @@ CONFIG_CRC_CCITT=m
1078CONFIG_CRC32=y 1169CONFIG_CRC32=y
1079# CONFIG_CRC7 is not set 1170# CONFIG_CRC7 is not set
1080# CONFIG_LIBCRC32C is not set 1171# CONFIG_LIBCRC32C is not set
1081CONFIG_PLIST=y
1082CONFIG_HAS_IOMEM=y 1172CONFIG_HAS_IOMEM=y
1083CONFIG_HAS_IOPORT=y 1173CONFIG_HAS_IOPORT=y
1084CONFIG_HAS_DMA=y 1174CONFIG_HAS_DMA=y
1175CONFIG_NLATTR=y
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
new file mode 100644
index 000000000000..9bb45b932f04
--- /dev/null
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -0,0 +1,1316 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.30
4# Tue Jun 23 22:57:16 2009
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
11CONFIG_MMU=y
12CONFIG_GENERIC_HARDIRQS=y
13CONFIG_STACKTRACE_SUPPORT=y
14CONFIG_HAVE_LATENCYTOP_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20CONFIG_GENERIC_HWEIGHT=y
21CONFIG_GENERIC_CALIBRATE_DELAY=y
22CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
23CONFIG_VECTORS_BASE=0xffff0000
24CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
25CONFIG_CONSTRUCTORS=y
26
27#
28# General setup
29#
30CONFIG_EXPERIMENTAL=y
31CONFIG_BROKEN_ON_SMP=y
32CONFIG_LOCK_KERNEL=y
33CONFIG_INIT_ENV_ARG_LIMIT=32
34CONFIG_LOCALVERSION=""
35# CONFIG_LOCALVERSION_AUTO is not set
36# CONFIG_SWAP is not set
37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
39# CONFIG_POSIX_MQUEUE is not set
40# CONFIG_BSD_PROCESS_ACCT is not set
41# CONFIG_TASKSTATS is not set
42# CONFIG_AUDIT is not set
43
44#
45# RCU Subsystem
46#
47CONFIG_CLASSIC_RCU=y
48# CONFIG_TREE_RCU is not set
49# CONFIG_PREEMPT_RCU is not set
50# CONFIG_TREE_RCU_TRACE is not set
51# CONFIG_PREEMPT_RCU_TRACE is not set
52CONFIG_IKCONFIG=y
53CONFIG_IKCONFIG_PROC=y
54CONFIG_LOG_BUF_SHIFT=14
55# CONFIG_GROUP_SCHED is not set
56# CONFIG_CGROUPS is not set
57CONFIG_SYSFS_DEPRECATED=y
58CONFIG_SYSFS_DEPRECATED_V2=y
59# CONFIG_RELAY is not set
60# CONFIG_NAMESPACES is not set
61CONFIG_BLK_DEV_INITRD=y
62CONFIG_INITRAMFS_SOURCE=""
63CONFIG_RD_GZIP=y
64# CONFIG_RD_BZIP2 is not set
65# CONFIG_RD_LZMA is not set
66CONFIG_CC_OPTIMIZE_FOR_SIZE=y
67CONFIG_SYSCTL=y
68CONFIG_ANON_INODES=y
69CONFIG_EMBEDDED=y
70CONFIG_UID16=y
71CONFIG_SYSCTL_SYSCALL=y
72CONFIG_KALLSYMS=y
73CONFIG_KALLSYMS_ALL=y
74# CONFIG_KALLSYMS_EXTRA_PASS is not set
75CONFIG_HOTPLUG=y
76CONFIG_PRINTK=y
77CONFIG_BUG=y
78CONFIG_ELF_CORE=y
79CONFIG_BASE_FULL=y
80CONFIG_FUTEX=y
81CONFIG_EPOLL=y
82CONFIG_SIGNALFD=y
83CONFIG_TIMERFD=y
84CONFIG_EVENTFD=y
85CONFIG_SHMEM=y
86CONFIG_AIO=y
87
88#
89# Performance Counters
90#
91CONFIG_VM_EVENT_COUNTERS=y
92# CONFIG_STRIP_ASM_SYMS is not set
93CONFIG_COMPAT_BRK=y
94CONFIG_SLAB=y
95# CONFIG_SLUB is not set
96# CONFIG_SLOB is not set
97# CONFIG_PROFILING is not set
98# CONFIG_MARKERS is not set
99CONFIG_HAVE_OPROFILE=y
100# CONFIG_KPROBES is not set
101CONFIG_HAVE_KPROBES=y
102CONFIG_HAVE_KRETPROBES=y
103CONFIG_HAVE_CLK=y
104
105#
106# GCOV-based kernel profiling
107#
108# CONFIG_SLOW_WORK is not set
109CONFIG_HAVE_GENERIC_DMA_COHERENT=y
110CONFIG_SLABINFO=y
111CONFIG_RT_MUTEXES=y
112CONFIG_BASE_SMALL=0
113CONFIG_MODULES=y
114# CONFIG_MODULE_FORCE_LOAD is not set
115CONFIG_MODULE_UNLOAD=y
116# CONFIG_MODULE_FORCE_UNLOAD is not set
117# CONFIG_MODVERSIONS is not set
118# CONFIG_MODULE_SRCVERSION_ALL is not set
119CONFIG_BLOCK=y
120CONFIG_LBDAF=y
121# CONFIG_BLK_DEV_BSG is not set
122# CONFIG_BLK_DEV_INTEGRITY is not set
123
124#
125# IO Schedulers
126#
127CONFIG_IOSCHED_NOOP=y
128CONFIG_IOSCHED_AS=y
129CONFIG_IOSCHED_DEADLINE=y
130CONFIG_IOSCHED_CFQ=y
131CONFIG_DEFAULT_AS=y
132# CONFIG_DEFAULT_DEADLINE is not set
133# CONFIG_DEFAULT_CFQ is not set
134# CONFIG_DEFAULT_NOOP is not set
135CONFIG_DEFAULT_IOSCHED="anticipatory"
136CONFIG_FREEZER=y
137
138#
139# System Type
140#
141# CONFIG_ARCH_AAEC2000 is not set
142# CONFIG_ARCH_INTEGRATOR is not set
143# CONFIG_ARCH_REALVIEW is not set
144# CONFIG_ARCH_VERSATILE is not set
145# CONFIG_ARCH_AT91 is not set
146# CONFIG_ARCH_CLPS711X is not set
147# CONFIG_ARCH_GEMINI is not set
148# CONFIG_ARCH_EBSA110 is not set
149# CONFIG_ARCH_EP93XX is not set
150# CONFIG_ARCH_FOOTBRIDGE is not set
151# CONFIG_ARCH_MXC is not set
152# CONFIG_ARCH_STMP3XXX is not set
153# CONFIG_ARCH_NETX is not set
154# CONFIG_ARCH_H720X is not set
155CONFIG_ARCH_NOMADIK=y
156# CONFIG_ARCH_IOP13XX is not set
157# CONFIG_ARCH_IOP32X is not set
158# CONFIG_ARCH_IOP33X is not set
159# CONFIG_ARCH_IXP23XX is not set
160# CONFIG_ARCH_IXP2000 is not set
161# CONFIG_ARCH_IXP4XX is not set
162# CONFIG_ARCH_L7200 is not set
163# CONFIG_ARCH_KIRKWOOD is not set
164# CONFIG_ARCH_LOKI is not set
165# CONFIG_ARCH_MV78XX0 is not set
166# CONFIG_ARCH_ORION5X is not set
167# CONFIG_ARCH_MMP is not set
168# CONFIG_ARCH_KS8695 is not set
169# CONFIG_ARCH_NS9XXX is not set
170# CONFIG_ARCH_W90X900 is not set
171# CONFIG_ARCH_PNX4008 is not set
172# CONFIG_ARCH_PXA is not set
173# CONFIG_ARCH_MSM is not set
174# CONFIG_ARCH_RPC is not set
175# CONFIG_ARCH_SA1100 is not set
176# CONFIG_ARCH_S3C2410 is not set
177# CONFIG_ARCH_S3C64XX is not set
178# CONFIG_ARCH_SHARK is not set
179# CONFIG_ARCH_LH7A40X is not set
180# CONFIG_ARCH_U300 is not set
181# CONFIG_ARCH_DAVINCI is not set
182# CONFIG_ARCH_OMAP is not set
183
184#
185# Nomadik boards
186#
187CONFIG_MACH_NOMADIK_8815NHK=y
188CONFIG_NOMADIK_8815=y
189CONFIG_I2C_BITBANG_8815NHK=y
190
191#
192# Processor Type
193#
194CONFIG_CPU_32=y
195CONFIG_CPU_ARM926T=y
196CONFIG_CPU_32v5=y
197CONFIG_CPU_ABRT_EV5TJ=y
198CONFIG_CPU_PABRT_NOIFAR=y
199CONFIG_CPU_CACHE_VIVT=y
200CONFIG_CPU_COPY_V4WB=y
201CONFIG_CPU_TLB_V4WBI=y
202CONFIG_CPU_CP15=y
203CONFIG_CPU_CP15_MMU=y
204
205#
206# Processor Features
207#
208CONFIG_ARM_THUMB=y
209# CONFIG_CPU_ICACHE_DISABLE is not set
210# CONFIG_CPU_DCACHE_DISABLE is not set
211# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
212# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
213CONFIG_OUTER_CACHE=y
214CONFIG_CACHE_L2X0=y
215CONFIG_ARM_VIC=y
216CONFIG_ARM_VIC_NR=2
217CONFIG_COMMON_CLKDEV=y
218
219#
220# Bus support
221#
222CONFIG_ARM_AMBA=y
223# CONFIG_PCI_SYSCALL is not set
224# CONFIG_ARCH_SUPPORTS_MSI is not set
225# CONFIG_PCCARD is not set
226
227#
228# Kernel Features
229#
230# CONFIG_NO_HZ is not set
231# CONFIG_HIGH_RES_TIMERS is not set
232CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
233CONFIG_VMSPLIT_3G=y
234# CONFIG_VMSPLIT_2G is not set
235# CONFIG_VMSPLIT_1G is not set
236CONFIG_PAGE_OFFSET=0xC0000000
237CONFIG_PREEMPT=y
238CONFIG_HZ=100
239CONFIG_AEABI=y
240CONFIG_OABI_COMPAT=y
241# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
242# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
243# CONFIG_HIGHMEM is not set
244CONFIG_SELECT_MEMORY_MODEL=y
245CONFIG_FLATMEM_MANUAL=y
246# CONFIG_DISCONTIGMEM_MANUAL is not set
247# CONFIG_SPARSEMEM_MANUAL is not set
248CONFIG_FLATMEM=y
249CONFIG_FLAT_NODE_MEM_MAP=y
250CONFIG_PAGEFLAGS_EXTENDED=y
251CONFIG_SPLIT_PTLOCK_CPUS=4096
252# CONFIG_PHYS_ADDR_T_64BIT is not set
253CONFIG_ZONE_DMA_FLAG=0
254CONFIG_VIRT_TO_BUS=y
255CONFIG_HAVE_MLOCK=y
256CONFIG_HAVE_MLOCKED_PAGE_BIT=y
257CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
258CONFIG_ALIGNMENT_TRAP=y
259# CONFIG_UACCESS_WITH_MEMCPY is not set
260
261#
262# Boot options
263#
264CONFIG_ZBOOT_ROM_TEXT=0x0
265CONFIG_ZBOOT_ROM_BSS=0x0
266CONFIG_CMDLINE=""
267# CONFIG_XIP_KERNEL is not set
268# CONFIG_KEXEC is not set
269
270#
271# CPU Power Management
272#
273# CONFIG_CPU_IDLE is not set
274
275#
276# Floating point emulation
277#
278
279#
280# At least one emulation must be selected
281#
282CONFIG_FPE_NWFPE=y
283# CONFIG_FPE_NWFPE_XP is not set
284# CONFIG_FPE_FASTFPE is not set
285# CONFIG_VFP is not set
286
287#
288# Userspace binary formats
289#
290CONFIG_BINFMT_ELF=y
291# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
292CONFIG_HAVE_AOUT=y
293# CONFIG_BINFMT_AOUT is not set
294# CONFIG_BINFMT_MISC is not set
295
296#
297# Power management options
298#
299CONFIG_PM=y
300# CONFIG_PM_DEBUG is not set
301CONFIG_PM_SLEEP=y
302CONFIG_SUSPEND=y
303CONFIG_SUSPEND_FREEZER=y
304# CONFIG_APM_EMULATION is not set
305CONFIG_ARCH_SUSPEND_POSSIBLE=y
306CONFIG_NET=y
307
308#
309# Networking options
310#
311CONFIG_PACKET=y
312# CONFIG_PACKET_MMAP is not set
313CONFIG_UNIX=y
314CONFIG_XFRM=y
315# CONFIG_XFRM_USER is not set
316# CONFIG_XFRM_SUB_POLICY is not set
317# CONFIG_XFRM_MIGRATE is not set
318# CONFIG_XFRM_STATISTICS is not set
319CONFIG_NET_KEY=y
320# CONFIG_NET_KEY_MIGRATE is not set
321CONFIG_INET=y
322CONFIG_IP_MULTICAST=y
323CONFIG_IP_ADVANCED_ROUTER=y
324CONFIG_ASK_IP_FIB_HASH=y
325# CONFIG_IP_FIB_TRIE is not set
326CONFIG_IP_FIB_HASH=y
327# CONFIG_IP_MULTIPLE_TABLES is not set
328# CONFIG_IP_ROUTE_MULTIPATH is not set
329# CONFIG_IP_ROUTE_VERBOSE is not set
330CONFIG_IP_PNP=y
331CONFIG_IP_PNP_DHCP=y
332CONFIG_IP_PNP_BOOTP=y
333# CONFIG_IP_PNP_RARP is not set
334CONFIG_NET_IPIP=y
335CONFIG_NET_IPGRE=y
336CONFIG_NET_IPGRE_BROADCAST=y
337CONFIG_IP_MROUTE=y
338# CONFIG_IP_PIMSM_V1 is not set
339# CONFIG_IP_PIMSM_V2 is not set
340# CONFIG_ARPD is not set
341# CONFIG_SYN_COOKIES is not set
342# CONFIG_INET_AH is not set
343# CONFIG_INET_ESP is not set
344# CONFIG_INET_IPCOMP is not set
345# CONFIG_INET_XFRM_TUNNEL is not set
346CONFIG_INET_TUNNEL=y
347CONFIG_INET_XFRM_MODE_TRANSPORT=y
348CONFIG_INET_XFRM_MODE_TUNNEL=y
349CONFIG_INET_XFRM_MODE_BEET=y
350# CONFIG_INET_LRO is not set
351CONFIG_INET_DIAG=y
352CONFIG_INET_TCP_DIAG=y
353# CONFIG_TCP_CONG_ADVANCED is not set
354CONFIG_TCP_CONG_CUBIC=y
355CONFIG_DEFAULT_TCP_CONG="cubic"
356# CONFIG_TCP_MD5SIG is not set
357# CONFIG_IPV6 is not set
358# CONFIG_NETWORK_SECMARK is not set
359# CONFIG_NETFILTER is not set
360# CONFIG_IP_DCCP is not set
361# CONFIG_IP_SCTP is not set
362# CONFIG_TIPC is not set
363# CONFIG_ATM is not set
364# CONFIG_BRIDGE is not set
365# CONFIG_NET_DSA is not set
366# CONFIG_VLAN_8021Q is not set
367# CONFIG_DECNET is not set
368# CONFIG_LLC2 is not set
369# CONFIG_IPX is not set
370# CONFIG_ATALK is not set
371# CONFIG_X25 is not set
372# CONFIG_LAPB is not set
373# CONFIG_ECONET is not set
374# CONFIG_WAN_ROUTER is not set
375# CONFIG_PHONET is not set
376# CONFIG_IEEE802154 is not set
377# CONFIG_NET_SCHED is not set
378# CONFIG_DCB is not set
379
380#
381# Network testing
382#
383# CONFIG_NET_PKTGEN is not set
384# CONFIG_HAMRADIO is not set
385# CONFIG_CAN is not set
386# CONFIG_IRDA is not set
387CONFIG_BT=m
388CONFIG_BT_L2CAP=m
389CONFIG_BT_SCO=m
390CONFIG_BT_RFCOMM=m
391CONFIG_BT_RFCOMM_TTY=y
392CONFIG_BT_BNEP=m
393CONFIG_BT_BNEP_MC_FILTER=y
394CONFIG_BT_BNEP_PROTO_FILTER=y
395CONFIG_BT_HIDP=m
396
397#
398# Bluetooth device drivers
399#
400CONFIG_BT_HCIUART=m
401CONFIG_BT_HCIUART_H4=y
402CONFIG_BT_HCIUART_BCSP=y
403# CONFIG_BT_HCIUART_LL is not set
404CONFIG_BT_HCIVHCI=m
405# CONFIG_AF_RXRPC is not set
406CONFIG_WIRELESS=y
407# CONFIG_CFG80211 is not set
408CONFIG_WIRELESS_OLD_REGULATORY=y
409# CONFIG_WIRELESS_EXT is not set
410# CONFIG_LIB80211 is not set
411
412#
413# CFG80211 needs to be enabled for MAC80211
414#
415CONFIG_MAC80211_DEFAULT_PS_VALUE=0
416# CONFIG_WIMAX is not set
417# CONFIG_RFKILL is not set
418# CONFIG_NET_9P is not set
419
420#
421# Device Drivers
422#
423
424#
425# Generic Driver Options
426#
427CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
428CONFIG_STANDALONE=y
429CONFIG_PREVENT_FIRMWARE_BUILD=y
430CONFIG_FW_LOADER=y
431CONFIG_FIRMWARE_IN_KERNEL=y
432CONFIG_EXTRA_FIRMWARE=""
433# CONFIG_DEBUG_DRIVER is not set
434# CONFIG_DEBUG_DEVRES is not set
435# CONFIG_SYS_HYPERVISOR is not set
436# CONFIG_CONNECTOR is not set
437CONFIG_MTD=y
438# CONFIG_MTD_DEBUG is not set
439# CONFIG_MTD_CONCAT is not set
440CONFIG_MTD_PARTITIONS=y
441CONFIG_MTD_TESTS=m
442# CONFIG_MTD_REDBOOT_PARTS is not set
443# CONFIG_MTD_CMDLINE_PARTS is not set
444# CONFIG_MTD_AFS_PARTS is not set
445# CONFIG_MTD_AR7_PARTS is not set
446
447#
448# User Modules And Translation Layers
449#
450CONFIG_MTD_CHAR=y
451CONFIG_MTD_BLKDEVS=y
452CONFIG_MTD_BLOCK=y
453# CONFIG_FTL is not set
454# CONFIG_NFTL is not set
455# CONFIG_INFTL is not set
456# CONFIG_RFD_FTL is not set
457# CONFIG_SSFDC is not set
458# CONFIG_MTD_OOPS is not set
459
460#
461# RAM/ROM/Flash chip drivers
462#
463# CONFIG_MTD_CFI is not set
464# CONFIG_MTD_JEDECPROBE is not set
465CONFIG_MTD_MAP_BANK_WIDTH_1=y
466CONFIG_MTD_MAP_BANK_WIDTH_2=y
467CONFIG_MTD_MAP_BANK_WIDTH_4=y
468# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
469# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
470# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
471CONFIG_MTD_CFI_I1=y
472CONFIG_MTD_CFI_I2=y
473# CONFIG_MTD_CFI_I4 is not set
474# CONFIG_MTD_CFI_I8 is not set
475# CONFIG_MTD_RAM is not set
476# CONFIG_MTD_ROM is not set
477# CONFIG_MTD_ABSENT is not set
478
479#
480# Mapping drivers for chip access
481#
482# CONFIG_MTD_COMPLEX_MAPPINGS is not set
483# CONFIG_MTD_PLATRAM is not set
484
485#
486# Self-contained MTD device drivers
487#
488# CONFIG_MTD_SLRAM is not set
489# CONFIG_MTD_PHRAM is not set
490# CONFIG_MTD_MTDRAM is not set
491# CONFIG_MTD_BLOCK2MTD is not set
492
493#
494# Disk-On-Chip Device Drivers
495#
496# CONFIG_MTD_DOC2000 is not set
497# CONFIG_MTD_DOC2001 is not set
498# CONFIG_MTD_DOC2001PLUS is not set
499CONFIG_MTD_NAND=y
500CONFIG_MTD_NAND_VERIFY_WRITE=y
501# CONFIG_MTD_NAND_ECC_SMC is not set
502# CONFIG_MTD_NAND_MUSEUM_IDS is not set
503# CONFIG_MTD_NAND_GPIO is not set
504CONFIG_MTD_NAND_IDS=y
505# CONFIG_MTD_NAND_DISKONCHIP is not set
506# CONFIG_MTD_NAND_NANDSIM is not set
507# CONFIG_MTD_NAND_PLATFORM is not set
508CONFIG_MTD_NAND_NOMADIK=y
509CONFIG_MTD_ONENAND=y
510CONFIG_MTD_ONENAND_VERIFY_WRITE=y
511CONFIG_MTD_ONENAND_GENERIC=y
512# CONFIG_MTD_ONENAND_OTP is not set
513# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
514# CONFIG_MTD_ONENAND_SIM is not set
515
516#
517# LPDDR flash memory drivers
518#
519# CONFIG_MTD_LPDDR is not set
520
521#
522# UBI - Unsorted block images
523#
524# CONFIG_MTD_UBI is not set
525# CONFIG_PARPORT is not set
526CONFIG_BLK_DEV=y
527# CONFIG_BLK_DEV_COW_COMMON is not set
528CONFIG_BLK_DEV_LOOP=y
529CONFIG_BLK_DEV_CRYPTOLOOP=y
530# CONFIG_BLK_DEV_NBD is not set
531CONFIG_BLK_DEV_RAM=y
532CONFIG_BLK_DEV_RAM_COUNT=16
533CONFIG_BLK_DEV_RAM_SIZE=4096
534# CONFIG_BLK_DEV_XIP is not set
535# CONFIG_CDROM_PKTCDVD is not set
536# CONFIG_ATA_OVER_ETH is not set
537# CONFIG_MG_DISK is not set
538CONFIG_MISC_DEVICES=y
539# CONFIG_ICS932S401 is not set
540# CONFIG_ENCLOSURE_SERVICES is not set
541# CONFIG_ISL29003 is not set
542# CONFIG_C2PORT is not set
543
544#
545# EEPROM support
546#
547# CONFIG_EEPROM_AT24 is not set
548# CONFIG_EEPROM_LEGACY is not set
549# CONFIG_EEPROM_MAX6875 is not set
550# CONFIG_EEPROM_93CX6 is not set
551CONFIG_HAVE_IDE=y
552# CONFIG_IDE is not set
553
554#
555# SCSI device support
556#
557# CONFIG_RAID_ATTRS is not set
558CONFIG_SCSI=y
559CONFIG_SCSI_DMA=y
560# CONFIG_SCSI_TGT is not set
561# CONFIG_SCSI_NETLINK is not set
562CONFIG_SCSI_PROC_FS=y
563
564#
565# SCSI support type (disk, tape, CD-ROM)
566#
567CONFIG_BLK_DEV_SD=y
568# CONFIG_CHR_DEV_ST is not set
569# CONFIG_CHR_DEV_OSST is not set
570# CONFIG_BLK_DEV_SR is not set
571CONFIG_CHR_DEV_SG=y
572# CONFIG_CHR_DEV_SCH is not set
573CONFIG_SCSI_MULTI_LUN=y
574CONFIG_SCSI_CONSTANTS=y
575CONFIG_SCSI_LOGGING=y
576CONFIG_SCSI_SCAN_ASYNC=y
577CONFIG_SCSI_WAIT_SCAN=m
578
579#
580# SCSI Transports
581#
582# CONFIG_SCSI_SPI_ATTRS is not set
583# CONFIG_SCSI_FC_ATTRS is not set
584# CONFIG_SCSI_ISCSI_ATTRS is not set
585# CONFIG_SCSI_SAS_LIBSAS is not set
586# CONFIG_SCSI_SRP_ATTRS is not set
587CONFIG_SCSI_LOWLEVEL=y
588# CONFIG_ISCSI_TCP is not set
589# CONFIG_LIBFC is not set
590# CONFIG_LIBFCOE is not set
591# CONFIG_SCSI_DEBUG is not set
592# CONFIG_SCSI_DH is not set
593# CONFIG_SCSI_OSD_INITIATOR is not set
594# CONFIG_ATA is not set
595# CONFIG_MD is not set
596CONFIG_NETDEVICES=y
597# CONFIG_DUMMY is not set
598# CONFIG_BONDING is not set
599# CONFIG_MACVLAN is not set
600# CONFIG_EQUALIZER is not set
601CONFIG_TUN=y
602# CONFIG_VETH is not set
603# CONFIG_PHYLIB is not set
604CONFIG_NET_ETHERNET=y
605CONFIG_MII=y
606# CONFIG_AX88796 is not set
607CONFIG_SMC91X=y
608# CONFIG_DM9000 is not set
609# CONFIG_ETHOC is not set
610# CONFIG_SMC911X is not set
611# CONFIG_SMSC911X is not set
612# CONFIG_DNET is not set
613# CONFIG_IBM_NEW_EMAC_ZMII is not set
614# CONFIG_IBM_NEW_EMAC_RGMII is not set
615# CONFIG_IBM_NEW_EMAC_TAH is not set
616# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
617# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
618# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
619# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
620# CONFIG_B44 is not set
621# CONFIG_KS8842 is not set
622CONFIG_NETDEV_1000=y
623CONFIG_NETDEV_10000=y
624
625#
626# Wireless LAN
627#
628# CONFIG_WLAN_PRE80211 is not set
629# CONFIG_WLAN_80211 is not set
630
631#
632# Enable WiMAX (Networking options) to see the WiMAX drivers
633#
634# CONFIG_WAN is not set
635CONFIG_PPP=m
636# CONFIG_PPP_MULTILINK is not set
637# CONFIG_PPP_FILTER is not set
638CONFIG_PPP_ASYNC=m
639CONFIG_PPP_SYNC_TTY=m
640CONFIG_PPP_DEFLATE=m
641CONFIG_PPP_BSDCOMP=m
642CONFIG_PPP_MPPE=m
643CONFIG_PPPOE=m
644# CONFIG_PPPOL2TP is not set
645# CONFIG_SLIP is not set
646CONFIG_SLHC=m
647CONFIG_NETCONSOLE=m
648# CONFIG_NETCONSOLE_DYNAMIC is not set
649CONFIG_NETPOLL=y
650# CONFIG_NETPOLL_TRAP is not set
651CONFIG_NET_POLL_CONTROLLER=y
652# CONFIG_ISDN is not set
653
654#
655# Input device support
656#
657CONFIG_INPUT=y
658# CONFIG_INPUT_FF_MEMLESS is not set
659# CONFIG_INPUT_POLLDEV is not set
660
661#
662# Userland interfaces
663#
664# CONFIG_INPUT_MOUSEDEV is not set
665# CONFIG_INPUT_JOYDEV is not set
666CONFIG_INPUT_EVDEV=y
667# CONFIG_INPUT_EVBUG is not set
668
669#
670# Input Device Drivers
671#
672CONFIG_INPUT_KEYBOARD=y
673# CONFIG_KEYBOARD_ATKBD is not set
674# CONFIG_KEYBOARD_SUNKBD is not set
675# CONFIG_KEYBOARD_LKKBD is not set
676# CONFIG_KEYBOARD_XTKBD is not set
677# CONFIG_KEYBOARD_NEWTON is not set
678# CONFIG_KEYBOARD_STOWAWAY is not set
679# CONFIG_KEYBOARD_GPIO is not set
680CONFIG_INPUT_MOUSE=y
681# CONFIG_MOUSE_PS2 is not set
682# CONFIG_MOUSE_SERIAL is not set
683# CONFIG_MOUSE_APPLETOUCH is not set
684# CONFIG_MOUSE_BCM5974 is not set
685# CONFIG_MOUSE_VSXXXAA is not set
686# CONFIG_MOUSE_GPIO is not set
687# CONFIG_MOUSE_SYNAPTICS_I2C is not set
688# CONFIG_INPUT_JOYSTICK is not set
689# CONFIG_INPUT_TABLET is not set
690# CONFIG_INPUT_TOUCHSCREEN is not set
691# CONFIG_INPUT_MISC is not set
692
693#
694# Hardware I/O ports
695#
696# CONFIG_SERIO is not set
697# CONFIG_GAMEPORT is not set
698
699#
700# Character devices
701#
702CONFIG_VT=y
703CONFIG_CONSOLE_TRANSLATIONS=y
704CONFIG_VT_CONSOLE=y
705CONFIG_HW_CONSOLE=y
706# CONFIG_VT_HW_CONSOLE_BINDING is not set
707CONFIG_DEVKMEM=y
708# CONFIG_SERIAL_NONSTANDARD is not set
709
710#
711# Serial drivers
712#
713# CONFIG_SERIAL_8250 is not set
714
715#
716# Non-8250 serial port support
717#
718# CONFIG_SERIAL_AMBA_PL010 is not set
719CONFIG_SERIAL_AMBA_PL011=y
720CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
721CONFIG_SERIAL_CORE=y
722CONFIG_SERIAL_CORE_CONSOLE=y
723CONFIG_UNIX98_PTYS=y
724# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
725# CONFIG_LEGACY_PTYS is not set
726# CONFIG_IPMI_HANDLER is not set
727# CONFIG_HW_RANDOM is not set
728# CONFIG_R3964 is not set
729# CONFIG_RAW_DRIVER is not set
730# CONFIG_TCG_TPM is not set
731CONFIG_I2C=y
732CONFIG_I2C_BOARDINFO=y
733CONFIG_I2C_CHARDEV=y
734CONFIG_I2C_HELPER_AUTO=y
735CONFIG_I2C_ALGOBIT=y
736
737#
738# I2C Hardware Bus support
739#
740
741#
742# I2C system bus drivers (mostly embedded / system-on-chip)
743#
744CONFIG_I2C_GPIO=y
745# CONFIG_I2C_OCORES is not set
746# CONFIG_I2C_SIMTEC is not set
747
748#
749# External I2C/SMBus adapter drivers
750#
751# CONFIG_I2C_PARPORT_LIGHT is not set
752# CONFIG_I2C_TAOS_EVM is not set
753
754#
755# Other I2C/SMBus bus drivers
756#
757# CONFIG_I2C_PCA_PLATFORM is not set
758# CONFIG_I2C_STUB is not set
759
760#
761# Miscellaneous I2C Chip support
762#
763# CONFIG_DS1682 is not set
764# CONFIG_SENSORS_PCF8574 is not set
765# CONFIG_PCF8575 is not set
766# CONFIG_SENSORS_PCA9539 is not set
767# CONFIG_SENSORS_TSL2550 is not set
768# CONFIG_I2C_DEBUG_CORE is not set
769# CONFIG_I2C_DEBUG_ALGO is not set
770# CONFIG_I2C_DEBUG_BUS is not set
771# CONFIG_I2C_DEBUG_CHIP is not set
772# CONFIG_SPI is not set
773CONFIG_ARCH_REQUIRE_GPIOLIB=y
774CONFIG_GPIOLIB=y
775CONFIG_DEBUG_GPIO=y
776# CONFIG_GPIO_SYSFS is not set
777
778#
779# Memory mapped GPIO expanders:
780#
781# CONFIG_GPIO_PL061 is not set
782
783#
784# I2C GPIO expanders:
785#
786# CONFIG_GPIO_MAX732X is not set
787# CONFIG_GPIO_PCA953X is not set
788# CONFIG_GPIO_PCF857X is not set
789
790#
791# PCI GPIO expanders:
792#
793
794#
795# SPI GPIO expanders:
796#
797# CONFIG_W1 is not set
798# CONFIG_POWER_SUPPLY is not set
799# CONFIG_HWMON is not set
800# CONFIG_THERMAL is not set
801# CONFIG_THERMAL_HWMON is not set
802# CONFIG_WATCHDOG is not set
803CONFIG_SSB_POSSIBLE=y
804
805#
806# Sonics Silicon Backplane
807#
808# CONFIG_SSB is not set
809
810#
811# Multifunction device drivers
812#
813# CONFIG_MFD_CORE is not set
814# CONFIG_MFD_SM501 is not set
815# CONFIG_MFD_ASIC3 is not set
816# CONFIG_HTC_EGPIO is not set
817# CONFIG_HTC_PASIC3 is not set
818# CONFIG_TPS65010 is not set
819# CONFIG_TWL4030_CORE is not set
820# CONFIG_MFD_TMIO is not set
821# CONFIG_MFD_T7L66XB is not set
822# CONFIG_MFD_TC6387XB is not set
823# CONFIG_MFD_TC6393XB is not set
824# CONFIG_PMIC_DA903X is not set
825# CONFIG_MFD_WM8400 is not set
826# CONFIG_MFD_WM8350_I2C is not set
827# CONFIG_MFD_PCF50633 is not set
828# CONFIG_AB3100_CORE is not set
829# CONFIG_MEDIA_SUPPORT is not set
830
831#
832# Graphics support
833#
834# CONFIG_VGASTATE is not set
835# CONFIG_VIDEO_OUTPUT_CONTROL is not set
836# CONFIG_FB is not set
837# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
838
839#
840# Display device support
841#
842# CONFIG_DISPLAY_SUPPORT is not set
843
844#
845# Console display driver support
846#
847# CONFIG_VGA_CONSOLE is not set
848CONFIG_DUMMY_CONSOLE=y
849# CONFIG_SOUND is not set
850CONFIG_HID_SUPPORT=y
851CONFIG_HID=y
852# CONFIG_HID_DEBUG is not set
853# CONFIG_HIDRAW is not set
854# CONFIG_HID_PID is not set
855
856#
857# Special HID drivers
858#
859# CONFIG_HID_APPLE is not set
860# CONFIG_HID_WACOM is not set
861CONFIG_USB_SUPPORT=y
862CONFIG_USB_ARCH_HAS_HCD=y
863# CONFIG_USB_ARCH_HAS_OHCI is not set
864# CONFIG_USB_ARCH_HAS_EHCI is not set
865# CONFIG_USB is not set
866# CONFIG_USB_OTG_WHITELIST is not set
867# CONFIG_USB_OTG_BLACKLIST_HUB is not set
868
869#
870# Enable Host or Gadget support to see Inventra options
871#
872
873#
874# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
875#
876# CONFIG_USB_GADGET is not set
877
878#
879# OTG and related infrastructure
880#
881# CONFIG_MMC is not set
882# CONFIG_MEMSTICK is not set
883# CONFIG_ACCESSIBILITY is not set
884# CONFIG_NEW_LEDS is not set
885CONFIG_RTC_LIB=y
886CONFIG_RTC_CLASS=y
887CONFIG_RTC_HCTOSYS=y
888CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
889# CONFIG_RTC_DEBUG is not set
890
891#
892# RTC interfaces
893#
894CONFIG_RTC_INTF_SYSFS=y
895CONFIG_RTC_INTF_PROC=y
896CONFIG_RTC_INTF_DEV=y
897# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
898# CONFIG_RTC_DRV_TEST is not set
899
900#
901# I2C RTC drivers
902#
903# CONFIG_RTC_DRV_DS1307 is not set
904# CONFIG_RTC_DRV_DS1374 is not set
905# CONFIG_RTC_DRV_DS1672 is not set
906# CONFIG_RTC_DRV_MAX6900 is not set
907# CONFIG_RTC_DRV_RS5C372 is not set
908# CONFIG_RTC_DRV_ISL1208 is not set
909# CONFIG_RTC_DRV_X1205 is not set
910# CONFIG_RTC_DRV_PCF8563 is not set
911# CONFIG_RTC_DRV_PCF8583 is not set
912# CONFIG_RTC_DRV_M41T80 is not set
913# CONFIG_RTC_DRV_S35390A is not set
914# CONFIG_RTC_DRV_FM3130 is not set
915# CONFIG_RTC_DRV_RX8581 is not set
916# CONFIG_RTC_DRV_RX8025 is not set
917
918#
919# SPI RTC drivers
920#
921
922#
923# Platform RTC drivers
924#
925# CONFIG_RTC_DRV_CMOS is not set
926# CONFIG_RTC_DRV_DS1286 is not set
927# CONFIG_RTC_DRV_DS1511 is not set
928# CONFIG_RTC_DRV_DS1553 is not set
929# CONFIG_RTC_DRV_DS1742 is not set
930# CONFIG_RTC_DRV_STK17TA8 is not set
931# CONFIG_RTC_DRV_M48T86 is not set
932# CONFIG_RTC_DRV_M48T35 is not set
933# CONFIG_RTC_DRV_M48T59 is not set
934# CONFIG_RTC_DRV_BQ4802 is not set
935# CONFIG_RTC_DRV_V3020 is not set
936
937#
938# on-CPU RTC drivers
939#
940# CONFIG_RTC_DRV_PL030 is not set
941# CONFIG_RTC_DRV_PL031 is not set
942# CONFIG_DMADEVICES is not set
943# CONFIG_AUXDISPLAY is not set
944# CONFIG_REGULATOR is not set
945# CONFIG_UIO is not set
946# CONFIG_STAGING is not set
947
948#
949# File systems
950#
951CONFIG_EXT2_FS=y
952# CONFIG_EXT2_FS_XATTR is not set
953# CONFIG_EXT2_FS_XIP is not set
954CONFIG_EXT3_FS=y
955# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
956CONFIG_EXT3_FS_XATTR=y
957# CONFIG_EXT3_FS_POSIX_ACL is not set
958# CONFIG_EXT3_FS_SECURITY is not set
959# CONFIG_EXT4_FS is not set
960CONFIG_JBD=y
961CONFIG_FS_MBCACHE=y
962# CONFIG_REISERFS_FS is not set
963# CONFIG_JFS_FS is not set
964CONFIG_FS_POSIX_ACL=y
965# CONFIG_XFS_FS is not set
966# CONFIG_GFS2_FS is not set
967# CONFIG_OCFS2_FS is not set
968# CONFIG_BTRFS_FS is not set
969CONFIG_FILE_LOCKING=y
970CONFIG_FSNOTIFY=y
971CONFIG_DNOTIFY=y
972CONFIG_INOTIFY=y
973CONFIG_INOTIFY_USER=y
974# CONFIG_QUOTA is not set
975# CONFIG_AUTOFS_FS is not set
976# CONFIG_AUTOFS4_FS is not set
977CONFIG_FUSE_FS=y
978# CONFIG_CUSE is not set
979
980#
981# Caches
982#
983# CONFIG_FSCACHE is not set
984
985#
986# CD-ROM/DVD Filesystems
987#
988# CONFIG_ISO9660_FS is not set
989# CONFIG_UDF_FS is not set
990
991#
992# DOS/FAT/NT Filesystems
993#
994CONFIG_FAT_FS=y
995CONFIG_MSDOS_FS=y
996CONFIG_VFAT_FS=y
997CONFIG_FAT_DEFAULT_CODEPAGE=437
998CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
999# CONFIG_NTFS_FS is not set
1000
1001#
1002# Pseudo filesystems
1003#
1004CONFIG_PROC_FS=y
1005CONFIG_PROC_SYSCTL=y
1006CONFIG_PROC_PAGE_MONITOR=y
1007CONFIG_SYSFS=y
1008CONFIG_TMPFS=y
1009# CONFIG_TMPFS_POSIX_ACL is not set
1010# CONFIG_HUGETLB_PAGE is not set
1011# CONFIG_CONFIGFS_FS is not set
1012CONFIG_MISC_FILESYSTEMS=y
1013# CONFIG_ADFS_FS is not set
1014# CONFIG_AFFS_FS is not set
1015# CONFIG_HFS_FS is not set
1016# CONFIG_HFSPLUS_FS is not set
1017# CONFIG_BEFS_FS is not set
1018# CONFIG_BFS_FS is not set
1019# CONFIG_EFS_FS is not set
1020CONFIG_JFFS2_FS=y
1021CONFIG_JFFS2_FS_DEBUG=0
1022CONFIG_JFFS2_FS_WRITEBUFFER=y
1023# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1024# CONFIG_JFFS2_SUMMARY is not set
1025# CONFIG_JFFS2_FS_XATTR is not set
1026# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1027CONFIG_JFFS2_ZLIB=y
1028# CONFIG_JFFS2_LZO is not set
1029CONFIG_JFFS2_RTIME=y
1030# CONFIG_JFFS2_RUBIN is not set
1031# CONFIG_CRAMFS is not set
1032# CONFIG_SQUASHFS is not set
1033# CONFIG_VXFS_FS is not set
1034# CONFIG_MINIX_FS is not set
1035# CONFIG_OMFS_FS is not set
1036# CONFIG_HPFS_FS is not set
1037# CONFIG_QNX4FS_FS is not set
1038# CONFIG_ROMFS_FS is not set
1039# CONFIG_SYSV_FS is not set
1040# CONFIG_UFS_FS is not set
1041# CONFIG_NILFS2_FS is not set
1042CONFIG_NETWORK_FILESYSTEMS=y
1043CONFIG_NFS_FS=y
1044CONFIG_NFS_V3=y
1045CONFIG_NFS_V3_ACL=y
1046# CONFIG_NFS_V4 is not set
1047CONFIG_ROOT_NFS=y
1048# CONFIG_NFSD is not set
1049CONFIG_LOCKD=y
1050CONFIG_LOCKD_V4=y
1051CONFIG_NFS_ACL_SUPPORT=y
1052CONFIG_NFS_COMMON=y
1053CONFIG_SUNRPC=y
1054# CONFIG_RPCSEC_GSS_KRB5 is not set
1055# CONFIG_RPCSEC_GSS_SPKM3 is not set
1056CONFIG_SMB_FS=m
1057# CONFIG_SMB_NLS_DEFAULT is not set
1058CONFIG_CIFS=m
1059# CONFIG_CIFS_STATS is not set
1060CONFIG_CIFS_WEAK_PW_HASH=y
1061# CONFIG_CIFS_XATTR is not set
1062# CONFIG_CIFS_DEBUG2 is not set
1063# CONFIG_CIFS_EXPERIMENTAL is not set
1064# CONFIG_NCP_FS is not set
1065# CONFIG_CODA_FS is not set
1066# CONFIG_AFS_FS is not set
1067
1068#
1069# Partition Types
1070#
1071# CONFIG_PARTITION_ADVANCED is not set
1072CONFIG_MSDOS_PARTITION=y
1073CONFIG_NLS=y
1074CONFIG_NLS_DEFAULT="iso8859-1"
1075CONFIG_NLS_CODEPAGE_437=y
1076# CONFIG_NLS_CODEPAGE_737 is not set
1077# CONFIG_NLS_CODEPAGE_775 is not set
1078# CONFIG_NLS_CODEPAGE_850 is not set
1079# CONFIG_NLS_CODEPAGE_852 is not set
1080# CONFIG_NLS_CODEPAGE_855 is not set
1081# CONFIG_NLS_CODEPAGE_857 is not set
1082# CONFIG_NLS_CODEPAGE_860 is not set
1083# CONFIG_NLS_CODEPAGE_861 is not set
1084# CONFIG_NLS_CODEPAGE_862 is not set
1085# CONFIG_NLS_CODEPAGE_863 is not set
1086# CONFIG_NLS_CODEPAGE_864 is not set
1087# CONFIG_NLS_CODEPAGE_865 is not set
1088# CONFIG_NLS_CODEPAGE_866 is not set
1089# CONFIG_NLS_CODEPAGE_869 is not set
1090# CONFIG_NLS_CODEPAGE_936 is not set
1091# CONFIG_NLS_CODEPAGE_950 is not set
1092# CONFIG_NLS_CODEPAGE_932 is not set
1093# CONFIG_NLS_CODEPAGE_949 is not set
1094# CONFIG_NLS_CODEPAGE_874 is not set
1095# CONFIG_NLS_ISO8859_8 is not set
1096# CONFIG_NLS_CODEPAGE_1250 is not set
1097# CONFIG_NLS_CODEPAGE_1251 is not set
1098CONFIG_NLS_ASCII=y
1099CONFIG_NLS_ISO8859_1=y
1100# CONFIG_NLS_ISO8859_2 is not set
1101# CONFIG_NLS_ISO8859_3 is not set
1102# CONFIG_NLS_ISO8859_4 is not set
1103# CONFIG_NLS_ISO8859_5 is not set
1104# CONFIG_NLS_ISO8859_6 is not set
1105# CONFIG_NLS_ISO8859_7 is not set
1106# CONFIG_NLS_ISO8859_9 is not set
1107# CONFIG_NLS_ISO8859_13 is not set
1108# CONFIG_NLS_ISO8859_14 is not set
1109CONFIG_NLS_ISO8859_15=y
1110# CONFIG_NLS_KOI8_R is not set
1111# CONFIG_NLS_KOI8_U is not set
1112# CONFIG_NLS_UTF8 is not set
1113# CONFIG_DLM is not set
1114
1115#
1116# Kernel hacking
1117#
1118# CONFIG_PRINTK_TIME is not set
1119CONFIG_ENABLE_WARN_DEPRECATED=y
1120# CONFIG_ENABLE_MUST_CHECK is not set
1121CONFIG_FRAME_WARN=1024
1122# CONFIG_MAGIC_SYSRQ is not set
1123# CONFIG_UNUSED_SYMBOLS is not set
1124# CONFIG_DEBUG_FS is not set
1125# CONFIG_HEADERS_CHECK is not set
1126CONFIG_DEBUG_KERNEL=y
1127# CONFIG_DEBUG_SHIRQ is not set
1128CONFIG_DETECT_SOFTLOCKUP=y
1129# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
1130CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
1131CONFIG_DETECT_HUNG_TASK=y
1132# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
1133CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
1134# CONFIG_SCHED_DEBUG is not set
1135# CONFIG_SCHEDSTATS is not set
1136# CONFIG_TIMER_STATS is not set
1137# CONFIG_DEBUG_OBJECTS is not set
1138# CONFIG_DEBUG_SLAB is not set
1139# CONFIG_DEBUG_KMEMLEAK is not set
1140# CONFIG_DEBUG_PREEMPT is not set
1141# CONFIG_DEBUG_RT_MUTEXES is not set
1142# CONFIG_RT_MUTEX_TESTER is not set
1143# CONFIG_DEBUG_SPINLOCK is not set
1144# CONFIG_DEBUG_MUTEXES is not set
1145# CONFIG_DEBUG_LOCK_ALLOC is not set
1146# CONFIG_PROVE_LOCKING is not set
1147# CONFIG_LOCK_STAT is not set
1148# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1149# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1150# CONFIG_DEBUG_KOBJECT is not set
1151# CONFIG_DEBUG_BUGVERBOSE is not set
1152CONFIG_DEBUG_INFO=y
1153# CONFIG_DEBUG_VM is not set
1154# CONFIG_DEBUG_WRITECOUNT is not set
1155# CONFIG_DEBUG_MEMORY_INIT is not set
1156# CONFIG_DEBUG_LIST is not set
1157# CONFIG_DEBUG_SG is not set
1158# CONFIG_DEBUG_NOTIFIERS is not set
1159# CONFIG_BOOT_PRINTK_DELAY is not set
1160# CONFIG_RCU_TORTURE_TEST is not set
1161# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1162# CONFIG_BACKTRACE_SELF_TEST is not set
1163# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
1164# CONFIG_FAULT_INJECTION is not set
1165# CONFIG_LATENCYTOP is not set
1166# CONFIG_SYSCTL_SYSCALL_CHECK is not set
1167# CONFIG_PAGE_POISONING is not set
1168CONFIG_HAVE_FUNCTION_TRACER=y
1169CONFIG_TRACING_SUPPORT=y
1170CONFIG_FTRACE=y
1171# CONFIG_FUNCTION_TRACER is not set
1172# CONFIG_IRQSOFF_TRACER is not set
1173# CONFIG_PREEMPT_TRACER is not set
1174# CONFIG_SCHED_TRACER is not set
1175# CONFIG_ENABLE_DEFAULT_TRACERS is not set
1176# CONFIG_BOOT_TRACER is not set
1177CONFIG_BRANCH_PROFILE_NONE=y
1178# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
1179# CONFIG_PROFILE_ALL_BRANCHES is not set
1180# CONFIG_STACK_TRACER is not set
1181# CONFIG_KMEMTRACE is not set
1182# CONFIG_WORKQUEUE_TRACER is not set
1183# CONFIG_BLK_DEV_IO_TRACE is not set
1184# CONFIG_SAMPLES is not set
1185CONFIG_HAVE_ARCH_KGDB=y
1186# CONFIG_KGDB is not set
1187CONFIG_ARM_UNWIND=y
1188# CONFIG_DEBUG_USER is not set
1189# CONFIG_DEBUG_ERRORS is not set
1190# CONFIG_DEBUG_STACK_USAGE is not set
1191# CONFIG_DEBUG_LL is not set
1192
1193#
1194# Security options
1195#
1196# CONFIG_KEYS is not set
1197# CONFIG_SECURITY is not set
1198# CONFIG_SECURITYFS is not set
1199# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1200CONFIG_CRYPTO=y
1201
1202#
1203# Crypto core or helper
1204#
1205# CONFIG_CRYPTO_FIPS is not set
1206CONFIG_CRYPTO_ALGAPI=y
1207CONFIG_CRYPTO_ALGAPI2=y
1208CONFIG_CRYPTO_AEAD2=y
1209CONFIG_CRYPTO_BLKCIPHER=y
1210CONFIG_CRYPTO_BLKCIPHER2=y
1211CONFIG_CRYPTO_HASH=y
1212CONFIG_CRYPTO_HASH2=y
1213CONFIG_CRYPTO_RNG2=y
1214CONFIG_CRYPTO_PCOMP=y
1215CONFIG_CRYPTO_MANAGER=y
1216CONFIG_CRYPTO_MANAGER2=y
1217# CONFIG_CRYPTO_GF128MUL is not set
1218# CONFIG_CRYPTO_NULL is not set
1219CONFIG_CRYPTO_WORKQUEUE=y
1220# CONFIG_CRYPTO_CRYPTD is not set
1221# CONFIG_CRYPTO_AUTHENC is not set
1222# CONFIG_CRYPTO_TEST is not set
1223
1224#
1225# Authenticated Encryption with Associated Data
1226#
1227# CONFIG_CRYPTO_CCM is not set
1228# CONFIG_CRYPTO_GCM is not set
1229# CONFIG_CRYPTO_SEQIV is not set
1230
1231#
1232# Block modes
1233#
1234CONFIG_CRYPTO_CBC=y
1235# CONFIG_CRYPTO_CTR is not set
1236# CONFIG_CRYPTO_CTS is not set
1237CONFIG_CRYPTO_ECB=m
1238# CONFIG_CRYPTO_LRW is not set
1239# CONFIG_CRYPTO_PCBC is not set
1240# CONFIG_CRYPTO_XTS is not set
1241
1242#
1243# Hash modes
1244#
1245# CONFIG_CRYPTO_HMAC is not set
1246# CONFIG_CRYPTO_XCBC is not set
1247
1248#
1249# Digest
1250#
1251# CONFIG_CRYPTO_CRC32C is not set
1252# CONFIG_CRYPTO_MD4 is not set
1253CONFIG_CRYPTO_MD5=y
1254# CONFIG_CRYPTO_MICHAEL_MIC is not set
1255# CONFIG_CRYPTO_RMD128 is not set
1256# CONFIG_CRYPTO_RMD160 is not set
1257# CONFIG_CRYPTO_RMD256 is not set
1258# CONFIG_CRYPTO_RMD320 is not set
1259CONFIG_CRYPTO_SHA1=y
1260# CONFIG_CRYPTO_SHA256 is not set
1261# CONFIG_CRYPTO_SHA512 is not set
1262# CONFIG_CRYPTO_TGR192 is not set
1263# CONFIG_CRYPTO_WP512 is not set
1264
1265#
1266# Ciphers
1267#
1268# CONFIG_CRYPTO_AES is not set
1269# CONFIG_CRYPTO_ANUBIS is not set
1270CONFIG_CRYPTO_ARC4=m
1271# CONFIG_CRYPTO_BLOWFISH is not set
1272# CONFIG_CRYPTO_CAMELLIA is not set
1273# CONFIG_CRYPTO_CAST5 is not set
1274# CONFIG_CRYPTO_CAST6 is not set
1275CONFIG_CRYPTO_DES=y
1276# CONFIG_CRYPTO_FCRYPT is not set
1277# CONFIG_CRYPTO_KHAZAD is not set
1278# CONFIG_CRYPTO_SALSA20 is not set
1279# CONFIG_CRYPTO_SEED is not set
1280# CONFIG_CRYPTO_SERPENT is not set
1281# CONFIG_CRYPTO_TEA is not set
1282# CONFIG_CRYPTO_TWOFISH is not set
1283
1284#
1285# Compression
1286#
1287# CONFIG_CRYPTO_DEFLATE is not set
1288# CONFIG_CRYPTO_ZLIB is not set
1289# CONFIG_CRYPTO_LZO is not set
1290
1291#
1292# Random Number Generation
1293#
1294# CONFIG_CRYPTO_ANSI_CPRNG is not set
1295CONFIG_CRYPTO_HW=y
1296# CONFIG_BINARY_PRINTF is not set
1297
1298#
1299# Library routines
1300#
1301CONFIG_BITREVERSE=y
1302CONFIG_GENERIC_FIND_LAST_BIT=y
1303CONFIG_CRC_CCITT=m
1304# CONFIG_CRC16 is not set
1305# CONFIG_CRC_T10DIF is not set
1306# CONFIG_CRC_ITU_T is not set
1307CONFIG_CRC32=y
1308# CONFIG_CRC7 is not set
1309# CONFIG_LIBCRC32C is not set
1310CONFIG_ZLIB_INFLATE=y
1311CONFIG_ZLIB_DEFLATE=y
1312CONFIG_DECOMPRESS_GZIP=y
1313CONFIG_HAS_IOMEM=y
1314CONFIG_HAS_IOPORT=y
1315CONFIG_HAS_DMA=y
1316CONFIG_NLATTR=y
diff --git a/arch/arm/configs/s5pc100_defconfig b/arch/arm/configs/s5pc100_defconfig
new file mode 100644
index 000000000000..b0d7d3d3a5e3
--- /dev/null
+++ b/arch/arm/configs/s5pc100_defconfig
@@ -0,0 +1,892 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.30
4# Wed Jul 1 15:53:07 2009
5#
6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_MMU=y
10CONFIG_NO_IOPORT=y
11CONFIG_GENERIC_HARDIRQS=y
12CONFIG_STACKTRACE_SUPPORT=y
13CONFIG_HAVE_LATENCYTOP_SUPPORT=y
14CONFIG_LOCKDEP_SUPPORT=y
15CONFIG_TRACE_IRQFLAGS_SUPPORT=y
16CONFIG_HARDIRQS_SW_RESEND=y
17CONFIG_GENERIC_IRQ_PROBE=y
18CONFIG_RWSEM_GENERIC_SPINLOCK=y
19CONFIG_GENERIC_HWEIGHT=y
20CONFIG_GENERIC_CALIBRATE_DELAY=y
21CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
22CONFIG_VECTORS_BASE=0xffff0000
23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
24CONFIG_CONSTRUCTORS=y
25
26#
27# General setup
28#
29CONFIG_EXPERIMENTAL=y
30CONFIG_BROKEN_ON_SMP=y
31CONFIG_INIT_ENV_ARG_LIMIT=32
32CONFIG_LOCALVERSION=""
33CONFIG_LOCALVERSION_AUTO=y
34CONFIG_SWAP=y
35# CONFIG_SYSVIPC is not set
36# CONFIG_BSD_PROCESS_ACCT is not set
37
38#
39# RCU Subsystem
40#
41CONFIG_CLASSIC_RCU=y
42# CONFIG_TREE_RCU is not set
43# CONFIG_PREEMPT_RCU is not set
44# CONFIG_TREE_RCU_TRACE is not set
45# CONFIG_PREEMPT_RCU_TRACE is not set
46# CONFIG_IKCONFIG is not set
47CONFIG_LOG_BUF_SHIFT=17
48# CONFIG_GROUP_SCHED is not set
49# CONFIG_CGROUPS is not set
50CONFIG_SYSFS_DEPRECATED=y
51CONFIG_SYSFS_DEPRECATED_V2=y
52# CONFIG_RELAY is not set
53CONFIG_NAMESPACES=y
54# CONFIG_UTS_NS is not set
55# CONFIG_USER_NS is not set
56# CONFIG_PID_NS is not set
57CONFIG_BLK_DEV_INITRD=y
58CONFIG_INITRAMFS_SOURCE=""
59CONFIG_RD_GZIP=y
60CONFIG_RD_BZIP2=y
61CONFIG_RD_LZMA=y
62CONFIG_CC_OPTIMIZE_FOR_SIZE=y
63CONFIG_SYSCTL=y
64CONFIG_ANON_INODES=y
65# CONFIG_EMBEDDED is not set
66CONFIG_UID16=y
67CONFIG_SYSCTL_SYSCALL=y
68CONFIG_KALLSYMS=y
69CONFIG_KALLSYMS_ALL=y
70# CONFIG_KALLSYMS_EXTRA_PASS is not set
71CONFIG_HOTPLUG=y
72CONFIG_PRINTK=y
73CONFIG_BUG=y
74CONFIG_ELF_CORE=y
75CONFIG_BASE_FULL=y
76CONFIG_FUTEX=y
77CONFIG_EPOLL=y
78CONFIG_SIGNALFD=y
79CONFIG_TIMERFD=y
80CONFIG_EVENTFD=y
81CONFIG_SHMEM=y
82CONFIG_AIO=y
83
84#
85# Performance Counters
86#
87CONFIG_VM_EVENT_COUNTERS=y
88CONFIG_SLUB_DEBUG=y
89# CONFIG_STRIP_ASM_SYMS is not set
90CONFIG_COMPAT_BRK=y
91# CONFIG_SLAB is not set
92CONFIG_SLUB=y
93# CONFIG_SLOB is not set
94# CONFIG_PROFILING is not set
95# CONFIG_MARKERS is not set
96CONFIG_HAVE_OPROFILE=y
97# CONFIG_KPROBES is not set
98CONFIG_HAVE_KPROBES=y
99CONFIG_HAVE_KRETPROBES=y
100CONFIG_HAVE_CLK=y
101
102#
103# GCOV-based kernel profiling
104#
105# CONFIG_SLOW_WORK is not set
106CONFIG_HAVE_GENERIC_DMA_COHERENT=y
107CONFIG_SLABINFO=y
108CONFIG_RT_MUTEXES=y
109CONFIG_BASE_SMALL=0
110CONFIG_MODULES=y
111# CONFIG_MODULE_FORCE_LOAD is not set
112CONFIG_MODULE_UNLOAD=y
113# CONFIG_MODULE_FORCE_UNLOAD is not set
114# CONFIG_MODVERSIONS is not set
115# CONFIG_MODULE_SRCVERSION_ALL is not set
116CONFIG_BLOCK=y
117CONFIG_LBDAF=y
118# CONFIG_BLK_DEV_BSG is not set
119# CONFIG_BLK_DEV_INTEGRITY is not set
120
121#
122# IO Schedulers
123#
124CONFIG_IOSCHED_NOOP=y
125CONFIG_IOSCHED_AS=y
126CONFIG_IOSCHED_DEADLINE=y
127CONFIG_IOSCHED_CFQ=y
128# CONFIG_DEFAULT_AS is not set
129# CONFIG_DEFAULT_DEADLINE is not set
130CONFIG_DEFAULT_CFQ=y
131# CONFIG_DEFAULT_NOOP is not set
132CONFIG_DEFAULT_IOSCHED="cfq"
133# CONFIG_FREEZER is not set
134
135#
136# System Type
137#
138# CONFIG_ARCH_AAEC2000 is not set
139# CONFIG_ARCH_INTEGRATOR is not set
140# CONFIG_ARCH_REALVIEW is not set
141# CONFIG_ARCH_VERSATILE is not set
142# CONFIG_ARCH_AT91 is not set
143# CONFIG_ARCH_CLPS711X is not set
144# CONFIG_ARCH_GEMINI is not set
145# CONFIG_ARCH_EBSA110 is not set
146# CONFIG_ARCH_EP93XX is not set
147# CONFIG_ARCH_FOOTBRIDGE is not set
148# CONFIG_ARCH_MXC is not set
149# CONFIG_ARCH_STMP3XXX is not set
150# CONFIG_ARCH_NETX is not set
151# CONFIG_ARCH_H720X is not set
152# CONFIG_ARCH_IOP13XX is not set
153# CONFIG_ARCH_IOP32X is not set
154# CONFIG_ARCH_IOP33X is not set
155# CONFIG_ARCH_IXP23XX is not set
156# CONFIG_ARCH_IXP2000 is not set
157# CONFIG_ARCH_IXP4XX is not set
158# CONFIG_ARCH_L7200 is not set
159# CONFIG_ARCH_KIRKWOOD is not set
160# CONFIG_ARCH_LOKI is not set
161# CONFIG_ARCH_MV78XX0 is not set
162# CONFIG_ARCH_ORION5X is not set
163# CONFIG_ARCH_MMP is not set
164# CONFIG_ARCH_KS8695 is not set
165# CONFIG_ARCH_NS9XXX is not set
166# CONFIG_ARCH_W90X900 is not set
167# CONFIG_ARCH_PNX4008 is not set
168# CONFIG_ARCH_PXA is not set
169# CONFIG_ARCH_MSM is not set
170# CONFIG_ARCH_RPC is not set
171# CONFIG_ARCH_SA1100 is not set
172# CONFIG_ARCH_S3C2410 is not set
173# CONFIG_ARCH_S3C64XX is not set
174CONFIG_ARCH_S5PC1XX=y
175# CONFIG_ARCH_SHARK is not set
176# CONFIG_ARCH_LH7A40X is not set
177# CONFIG_ARCH_U300 is not set
178# CONFIG_ARCH_DAVINCI is not set
179# CONFIG_ARCH_OMAP is not set
180CONFIG_PLAT_S3C=y
181
182#
183# Boot options
184#
185# CONFIG_S3C_BOOT_ERROR_RESET is not set
186CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
187
188#
189# Power management
190#
191CONFIG_S3C_LOWLEVEL_UART_PORT=0
192CONFIG_S3C_GPIO_SPACE=0
193CONFIG_S3C_GPIO_TRACK=y
194CONFIG_S3C_GPIO_PULL_UPDOWN=y
195CONFIG_PLAT_S5PC1XX=y
196CONFIG_CPU_S5PC100_INIT=y
197CONFIG_CPU_S5PC100_CLOCK=y
198CONFIG_S5PC100_SETUP_I2C0=y
199CONFIG_CPU_S5PC100=y
200CONFIG_MACH_SMDKC100=y
201
202#
203# Processor Type
204#
205CONFIG_CPU_32=y
206CONFIG_CPU_32v6K=y
207CONFIG_CPU_V7=y
208CONFIG_CPU_32v7=y
209CONFIG_CPU_ABRT_EV7=y
210CONFIG_CPU_PABRT_IFAR=y
211CONFIG_CPU_CACHE_V7=y
212CONFIG_CPU_CACHE_VIPT=y
213CONFIG_CPU_COPY_V6=y
214CONFIG_CPU_TLB_V7=y
215CONFIG_CPU_HAS_ASID=y
216CONFIG_CPU_CP15=y
217CONFIG_CPU_CP15_MMU=y
218
219#
220# Processor Features
221#
222CONFIG_ARM_THUMB=y
223# CONFIG_ARM_THUMBEE is not set
224# CONFIG_CPU_ICACHE_DISABLE is not set
225# CONFIG_CPU_DCACHE_DISABLE is not set
226# CONFIG_CPU_BPREDICT_DISABLE is not set
227CONFIG_HAS_TLS_REG=y
228# CONFIG_ARM_ERRATA_430973 is not set
229# CONFIG_ARM_ERRATA_458693 is not set
230# CONFIG_ARM_ERRATA_460075 is not set
231CONFIG_ARM_VIC=y
232CONFIG_ARM_VIC_NR=2
233
234#
235# Bus support
236#
237# CONFIG_PCI_SYSCALL is not set
238# CONFIG_ARCH_SUPPORTS_MSI is not set
239# CONFIG_PCCARD is not set
240
241#
242# Kernel Features
243#
244CONFIG_VMSPLIT_3G=y
245# CONFIG_VMSPLIT_2G is not set
246# CONFIG_VMSPLIT_1G is not set
247CONFIG_PAGE_OFFSET=0xC0000000
248# CONFIG_PREEMPT is not set
249CONFIG_HZ=100
250CONFIG_AEABI=y
251CONFIG_OABI_COMPAT=y
252# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
253# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
254# CONFIG_HIGHMEM is not set
255CONFIG_SELECT_MEMORY_MODEL=y
256CONFIG_FLATMEM_MANUAL=y
257# CONFIG_DISCONTIGMEM_MANUAL is not set
258# CONFIG_SPARSEMEM_MANUAL is not set
259CONFIG_FLATMEM=y
260CONFIG_FLAT_NODE_MEM_MAP=y
261CONFIG_PAGEFLAGS_EXTENDED=y
262CONFIG_SPLIT_PTLOCK_CPUS=4
263# CONFIG_PHYS_ADDR_T_64BIT is not set
264CONFIG_ZONE_DMA_FLAG=0
265CONFIG_VIRT_TO_BUS=y
266CONFIG_HAVE_MLOCK=y
267CONFIG_HAVE_MLOCKED_PAGE_BIT=y
268CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
269CONFIG_ALIGNMENT_TRAP=y
270# CONFIG_UACCESS_WITH_MEMCPY is not set
271
272#
273# Boot options
274#
275CONFIG_ZBOOT_ROM_TEXT=0
276CONFIG_ZBOOT_ROM_BSS=0
277CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc console=ttySAC2,115200 mem=128M"
278# CONFIG_XIP_KERNEL is not set
279# CONFIG_KEXEC is not set
280
281#
282# CPU Power Management
283#
284# CONFIG_CPU_IDLE is not set
285
286#
287# Floating point emulation
288#
289
290#
291# At least one emulation must be selected
292#
293# CONFIG_FPE_NWFPE is not set
294# CONFIG_FPE_FASTFPE is not set
295# CONFIG_VFP is not set
296
297#
298# Userspace binary formats
299#
300CONFIG_BINFMT_ELF=y
301# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
302CONFIG_HAVE_AOUT=y
303# CONFIG_BINFMT_AOUT is not set
304# CONFIG_BINFMT_MISC is not set
305
306#
307# Power management options
308#
309# CONFIG_PM is not set
310CONFIG_ARCH_SUSPEND_POSSIBLE=y
311# CONFIG_NET is not set
312
313#
314# Device Drivers
315#
316
317#
318# Generic Driver Options
319#
320CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
321CONFIG_STANDALONE=y
322CONFIG_PREVENT_FIRMWARE_BUILD=y
323CONFIG_FW_LOADER=y
324CONFIG_FIRMWARE_IN_KERNEL=y
325CONFIG_EXTRA_FIRMWARE=""
326# CONFIG_DEBUG_DRIVER is not set
327# CONFIG_DEBUG_DEVRES is not set
328# CONFIG_SYS_HYPERVISOR is not set
329# CONFIG_MTD is not set
330# CONFIG_PARPORT is not set
331CONFIG_BLK_DEV=y
332# CONFIG_BLK_DEV_COW_COMMON is not set
333CONFIG_BLK_DEV_LOOP=y
334# CONFIG_BLK_DEV_CRYPTOLOOP is not set
335CONFIG_BLK_DEV_RAM=y
336CONFIG_BLK_DEV_RAM_COUNT=16
337CONFIG_BLK_DEV_RAM_SIZE=8192
338# CONFIG_BLK_DEV_XIP is not set
339# CONFIG_CDROM_PKTCDVD is not set
340# CONFIG_MG_DISK is not set
341CONFIG_MISC_DEVICES=y
342# CONFIG_ICS932S401 is not set
343# CONFIG_ENCLOSURE_SERVICES is not set
344# CONFIG_ISL29003 is not set
345# CONFIG_C2PORT is not set
346
347#
348# EEPROM support
349#
350CONFIG_EEPROM_AT24=y
351# CONFIG_EEPROM_LEGACY is not set
352# CONFIG_EEPROM_MAX6875 is not set
353# CONFIG_EEPROM_93CX6 is not set
354CONFIG_HAVE_IDE=y
355# CONFIG_IDE is not set
356
357#
358# SCSI device support
359#
360# CONFIG_RAID_ATTRS is not set
361# CONFIG_SCSI is not set
362# CONFIG_SCSI_DMA is not set
363# CONFIG_SCSI_NETLINK is not set
364# CONFIG_ATA is not set
365# CONFIG_MD is not set
366
367#
368# Input device support
369#
370CONFIG_INPUT=y
371# CONFIG_INPUT_FF_MEMLESS is not set
372# CONFIG_INPUT_POLLDEV is not set
373
374#
375# Userland interfaces
376#
377CONFIG_INPUT_MOUSEDEV=y
378CONFIG_INPUT_MOUSEDEV_PSAUX=y
379CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
380CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
381# CONFIG_INPUT_JOYDEV is not set
382# CONFIG_INPUT_EVDEV is not set
383# CONFIG_INPUT_EVBUG is not set
384
385#
386# Input Device Drivers
387#
388CONFIG_INPUT_KEYBOARD=y
389CONFIG_KEYBOARD_ATKBD=y
390# CONFIG_KEYBOARD_SUNKBD is not set
391# CONFIG_KEYBOARD_LKKBD is not set
392# CONFIG_KEYBOARD_XTKBD is not set
393# CONFIG_KEYBOARD_NEWTON is not set
394# CONFIG_KEYBOARD_STOWAWAY is not set
395# CONFIG_KEYBOARD_GPIO is not set
396CONFIG_INPUT_MOUSE=y
397CONFIG_MOUSE_PS2=y
398CONFIG_MOUSE_PS2_ALPS=y
399CONFIG_MOUSE_PS2_LOGIPS2PP=y
400CONFIG_MOUSE_PS2_SYNAPTICS=y
401CONFIG_MOUSE_PS2_TRACKPOINT=y
402# CONFIG_MOUSE_PS2_ELANTECH is not set
403# CONFIG_MOUSE_PS2_TOUCHKIT is not set
404# CONFIG_MOUSE_SERIAL is not set
405# CONFIG_MOUSE_APPLETOUCH is not set
406# CONFIG_MOUSE_BCM5974 is not set
407# CONFIG_MOUSE_VSXXXAA is not set
408# CONFIG_MOUSE_GPIO is not set
409# CONFIG_MOUSE_SYNAPTICS_I2C is not set
410# CONFIG_INPUT_JOYSTICK is not set
411# CONFIG_INPUT_TABLET is not set
412# CONFIG_INPUT_TOUCHSCREEN is not set
413# CONFIG_INPUT_MISC is not set
414
415#
416# Hardware I/O ports
417#
418CONFIG_SERIO=y
419CONFIG_SERIO_SERPORT=y
420CONFIG_SERIO_LIBPS2=y
421# CONFIG_SERIO_RAW is not set
422# CONFIG_GAMEPORT is not set
423
424#
425# Character devices
426#
427CONFIG_VT=y
428CONFIG_CONSOLE_TRANSLATIONS=y
429CONFIG_VT_CONSOLE=y
430CONFIG_HW_CONSOLE=y
431# CONFIG_VT_HW_CONSOLE_BINDING is not set
432CONFIG_DEVKMEM=y
433# CONFIG_SERIAL_NONSTANDARD is not set
434
435#
436# Serial drivers
437#
438CONFIG_SERIAL_8250=y
439# CONFIG_SERIAL_8250_CONSOLE is not set
440CONFIG_SERIAL_8250_NR_UARTS=4
441CONFIG_SERIAL_8250_RUNTIME_UARTS=4
442# CONFIG_SERIAL_8250_EXTENDED is not set
443
444#
445# Non-8250 serial port support
446#
447CONFIG_SERIAL_SAMSUNG=y
448CONFIG_SERIAL_SAMSUNG_UARTS=3
449# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
450CONFIG_SERIAL_SAMSUNG_CONSOLE=y
451CONFIG_SERIAL_CORE=y
452CONFIG_SERIAL_CORE_CONSOLE=y
453CONFIG_UNIX98_PTYS=y
454# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
455CONFIG_LEGACY_PTYS=y
456CONFIG_LEGACY_PTY_COUNT=256
457# CONFIG_IPMI_HANDLER is not set
458CONFIG_HW_RANDOM=y
459# CONFIG_HW_RANDOM_TIMERIOMEM is not set
460# CONFIG_R3964 is not set
461# CONFIG_RAW_DRIVER is not set
462# CONFIG_TCG_TPM is not set
463CONFIG_I2C=y
464CONFIG_I2C_BOARDINFO=y
465CONFIG_I2C_CHARDEV=y
466CONFIG_I2C_HELPER_AUTO=y
467
468#
469# I2C Hardware Bus support
470#
471
472#
473# I2C system bus drivers (mostly embedded / system-on-chip)
474#
475# CONFIG_I2C_GPIO is not set
476# CONFIG_I2C_OCORES is not set
477# CONFIG_I2C_SIMTEC is not set
478
479#
480# External I2C/SMBus adapter drivers
481#
482# CONFIG_I2C_PARPORT_LIGHT is not set
483# CONFIG_I2C_TAOS_EVM is not set
484
485#
486# Other I2C/SMBus bus drivers
487#
488# CONFIG_I2C_PCA_PLATFORM is not set
489# CONFIG_I2C_STUB is not set
490
491#
492# Miscellaneous I2C Chip support
493#
494# CONFIG_DS1682 is not set
495# CONFIG_SENSORS_PCF8574 is not set
496# CONFIG_PCF8575 is not set
497# CONFIG_SENSORS_PCA9539 is not set
498# CONFIG_SENSORS_TSL2550 is not set
499# CONFIG_I2C_DEBUG_CORE is not set
500# CONFIG_I2C_DEBUG_ALGO is not set
501# CONFIG_I2C_DEBUG_BUS is not set
502# CONFIG_I2C_DEBUG_CHIP is not set
503# CONFIG_SPI is not set
504CONFIG_ARCH_REQUIRE_GPIOLIB=y
505CONFIG_GPIOLIB=y
506# CONFIG_DEBUG_GPIO is not set
507# CONFIG_GPIO_SYSFS is not set
508
509#
510# Memory mapped GPIO expanders:
511#
512
513#
514# I2C GPIO expanders:
515#
516# CONFIG_GPIO_MAX732X is not set
517# CONFIG_GPIO_PCA953X is not set
518# CONFIG_GPIO_PCF857X is not set
519
520#
521# PCI GPIO expanders:
522#
523
524#
525# SPI GPIO expanders:
526#
527# CONFIG_W1 is not set
528# CONFIG_POWER_SUPPLY is not set
529CONFIG_HWMON=y
530# CONFIG_HWMON_VID is not set
531# CONFIG_SENSORS_AD7414 is not set
532# CONFIG_SENSORS_AD7418 is not set
533# CONFIG_SENSORS_ADM1021 is not set
534# CONFIG_SENSORS_ADM1025 is not set
535# CONFIG_SENSORS_ADM1026 is not set
536# CONFIG_SENSORS_ADM1029 is not set
537# CONFIG_SENSORS_ADM1031 is not set
538# CONFIG_SENSORS_ADM9240 is not set
539# CONFIG_SENSORS_ADT7462 is not set
540# CONFIG_SENSORS_ADT7470 is not set
541# CONFIG_SENSORS_ADT7473 is not set
542# CONFIG_SENSORS_ADT7475 is not set
543# CONFIG_SENSORS_ATXP1 is not set
544# CONFIG_SENSORS_DS1621 is not set
545# CONFIG_SENSORS_F71805F is not set
546# CONFIG_SENSORS_F71882FG is not set
547# CONFIG_SENSORS_F75375S is not set
548# CONFIG_SENSORS_G760A is not set
549# CONFIG_SENSORS_GL518SM is not set
550# CONFIG_SENSORS_GL520SM is not set
551# CONFIG_SENSORS_IT87 is not set
552# CONFIG_SENSORS_LM63 is not set
553# CONFIG_SENSORS_LM75 is not set
554# CONFIG_SENSORS_LM77 is not set
555# CONFIG_SENSORS_LM78 is not set
556# CONFIG_SENSORS_LM80 is not set
557# CONFIG_SENSORS_LM83 is not set
558# CONFIG_SENSORS_LM85 is not set
559# CONFIG_SENSORS_LM87 is not set
560# CONFIG_SENSORS_LM90 is not set
561# CONFIG_SENSORS_LM92 is not set
562# CONFIG_SENSORS_LM93 is not set
563# CONFIG_SENSORS_LTC4215 is not set
564# CONFIG_SENSORS_LTC4245 is not set
565# CONFIG_SENSORS_LM95241 is not set
566# CONFIG_SENSORS_MAX1619 is not set
567# CONFIG_SENSORS_MAX6650 is not set
568# CONFIG_SENSORS_PC87360 is not set
569# CONFIG_SENSORS_PC87427 is not set
570# CONFIG_SENSORS_PCF8591 is not set
571# CONFIG_SENSORS_SHT15 is not set
572# CONFIG_SENSORS_DME1737 is not set
573# CONFIG_SENSORS_SMSC47M1 is not set
574# CONFIG_SENSORS_SMSC47M192 is not set
575# CONFIG_SENSORS_SMSC47B397 is not set
576# CONFIG_SENSORS_ADS7828 is not set
577# CONFIG_SENSORS_THMC50 is not set
578# CONFIG_SENSORS_TMP401 is not set
579# CONFIG_SENSORS_VT1211 is not set
580# CONFIG_SENSORS_W83781D is not set
581# CONFIG_SENSORS_W83791D is not set
582# CONFIG_SENSORS_W83792D is not set
583# CONFIG_SENSORS_W83793 is not set
584# CONFIG_SENSORS_W83L785TS is not set
585# CONFIG_SENSORS_W83L786NG is not set
586# CONFIG_SENSORS_W83627HF is not set
587# CONFIG_SENSORS_W83627EHF is not set
588# CONFIG_HWMON_DEBUG_CHIP is not set
589# CONFIG_THERMAL is not set
590# CONFIG_THERMAL_HWMON is not set
591# CONFIG_WATCHDOG is not set
592CONFIG_SSB_POSSIBLE=y
593
594#
595# Sonics Silicon Backplane
596#
597# CONFIG_SSB is not set
598
599#
600# Multifunction device drivers
601#
602# CONFIG_MFD_CORE is not set
603# CONFIG_MFD_SM501 is not set
604# CONFIG_MFD_ASIC3 is not set
605# CONFIG_HTC_EGPIO is not set
606# CONFIG_HTC_PASIC3 is not set
607# CONFIG_TPS65010 is not set
608# CONFIG_TWL4030_CORE is not set
609# CONFIG_MFD_TMIO is not set
610# CONFIG_MFD_T7L66XB is not set
611# CONFIG_MFD_TC6387XB is not set
612# CONFIG_MFD_TC6393XB is not set
613# CONFIG_PMIC_DA903X is not set
614# CONFIG_MFD_WM8400 is not set
615# CONFIG_MFD_WM8350_I2C is not set
616# CONFIG_MFD_PCF50633 is not set
617# CONFIG_AB3100_CORE is not set
618# CONFIG_MEDIA_SUPPORT is not set
619
620#
621# Graphics support
622#
623# CONFIG_VGASTATE is not set
624# CONFIG_VIDEO_OUTPUT_CONTROL is not set
625# CONFIG_FB is not set
626# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
627
628#
629# Display device support
630#
631# CONFIG_DISPLAY_SUPPORT is not set
632
633#
634# Console display driver support
635#
636# CONFIG_VGA_CONSOLE is not set
637CONFIG_DUMMY_CONSOLE=y
638# CONFIG_SOUND is not set
639CONFIG_HID_SUPPORT=y
640CONFIG_HID=y
641CONFIG_HID_DEBUG=y
642# CONFIG_HIDRAW is not set
643# CONFIG_HID_PID is not set
644
645#
646# Special HID drivers
647#
648CONFIG_USB_SUPPORT=y
649CONFIG_USB_ARCH_HAS_HCD=y
650# CONFIG_USB_ARCH_HAS_OHCI is not set
651# CONFIG_USB_ARCH_HAS_EHCI is not set
652# CONFIG_USB is not set
653
654#
655# Enable Host or Gadget support to see Inventra options
656#
657
658#
659# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
660#
661# CONFIG_USB_GADGET is not set
662
663#
664# OTG and related infrastructure
665#
666CONFIG_MMC=y
667CONFIG_MMC_DEBUG=y
668CONFIG_MMC_UNSAFE_RESUME=y
669
670#
671# MMC/SD/SDIO Card Drivers
672#
673CONFIG_MMC_BLOCK=y
674CONFIG_MMC_BLOCK_BOUNCE=y
675CONFIG_SDIO_UART=y
676# CONFIG_MMC_TEST is not set
677
678#
679# MMC/SD/SDIO Host Controller Drivers
680#
681CONFIG_MMC_SDHCI=y
682# CONFIG_MMC_SDHCI_PLTFM is not set
683# CONFIG_MEMSTICK is not set
684# CONFIG_ACCESSIBILITY is not set
685# CONFIG_NEW_LEDS is not set
686CONFIG_RTC_LIB=y
687# CONFIG_RTC_CLASS is not set
688# CONFIG_DMADEVICES is not set
689# CONFIG_AUXDISPLAY is not set
690# CONFIG_REGULATOR is not set
691# CONFIG_UIO is not set
692# CONFIG_STAGING is not set
693
694#
695# File systems
696#
697CONFIG_EXT2_FS=y
698# CONFIG_EXT2_FS_XATTR is not set
699# CONFIG_EXT2_FS_XIP is not set
700CONFIG_EXT3_FS=y
701# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
702CONFIG_EXT3_FS_XATTR=y
703CONFIG_EXT3_FS_POSIX_ACL=y
704CONFIG_EXT3_FS_SECURITY=y
705# CONFIG_EXT4_FS is not set
706CONFIG_JBD=y
707CONFIG_FS_MBCACHE=y
708# CONFIG_REISERFS_FS is not set
709# CONFIG_JFS_FS is not set
710CONFIG_FS_POSIX_ACL=y
711# CONFIG_XFS_FS is not set
712# CONFIG_GFS2_FS is not set
713# CONFIG_BTRFS_FS is not set
714CONFIG_FILE_LOCKING=y
715CONFIG_FSNOTIFY=y
716CONFIG_DNOTIFY=y
717CONFIG_INOTIFY=y
718CONFIG_INOTIFY_USER=y
719# CONFIG_QUOTA is not set
720# CONFIG_AUTOFS_FS is not set
721# CONFIG_AUTOFS4_FS is not set
722# CONFIG_FUSE_FS is not set
723CONFIG_GENERIC_ACL=y
724
725#
726# Caches
727#
728# CONFIG_FSCACHE is not set
729
730#
731# CD-ROM/DVD Filesystems
732#
733# CONFIG_ISO9660_FS is not set
734# CONFIG_UDF_FS is not set
735
736#
737# DOS/FAT/NT Filesystems
738#
739# CONFIG_MSDOS_FS is not set
740# CONFIG_VFAT_FS is not set
741# CONFIG_NTFS_FS is not set
742
743#
744# Pseudo filesystems
745#
746CONFIG_PROC_FS=y
747CONFIG_PROC_SYSCTL=y
748CONFIG_PROC_PAGE_MONITOR=y
749CONFIG_SYSFS=y
750CONFIG_TMPFS=y
751CONFIG_TMPFS_POSIX_ACL=y
752# CONFIG_HUGETLB_PAGE is not set
753# CONFIG_CONFIGFS_FS is not set
754CONFIG_MISC_FILESYSTEMS=y
755# CONFIG_ADFS_FS is not set
756# CONFIG_AFFS_FS is not set
757# CONFIG_HFS_FS is not set
758# CONFIG_HFSPLUS_FS is not set
759# CONFIG_BEFS_FS is not set
760# CONFIG_BFS_FS is not set
761# CONFIG_EFS_FS is not set
762CONFIG_CRAMFS=y
763# CONFIG_SQUASHFS is not set
764# CONFIG_VXFS_FS is not set
765# CONFIG_MINIX_FS is not set
766# CONFIG_OMFS_FS is not set
767# CONFIG_HPFS_FS is not set
768# CONFIG_QNX4FS_FS is not set
769CONFIG_ROMFS_FS=y
770CONFIG_ROMFS_BACKED_BY_BLOCK=y
771# CONFIG_ROMFS_BACKED_BY_MTD is not set
772# CONFIG_ROMFS_BACKED_BY_BOTH is not set
773CONFIG_ROMFS_ON_BLOCK=y
774# CONFIG_SYSV_FS is not set
775# CONFIG_UFS_FS is not set
776# CONFIG_NILFS2_FS is not set
777
778#
779# Partition Types
780#
781# CONFIG_PARTITION_ADVANCED is not set
782CONFIG_MSDOS_PARTITION=y
783# CONFIG_NLS is not set
784
785#
786# Kernel hacking
787#
788# CONFIG_PRINTK_TIME is not set
789CONFIG_ENABLE_WARN_DEPRECATED=y
790CONFIG_ENABLE_MUST_CHECK=y
791CONFIG_FRAME_WARN=1024
792CONFIG_MAGIC_SYSRQ=y
793# CONFIG_UNUSED_SYMBOLS is not set
794# CONFIG_DEBUG_FS is not set
795# CONFIG_HEADERS_CHECK is not set
796CONFIG_DEBUG_KERNEL=y
797# CONFIG_DEBUG_SHIRQ is not set
798CONFIG_DETECT_SOFTLOCKUP=y
799# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
800CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
801CONFIG_DETECT_HUNG_TASK=y
802# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
803CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
804CONFIG_SCHED_DEBUG=y
805# CONFIG_SCHEDSTATS is not set
806# CONFIG_TIMER_STATS is not set
807# CONFIG_DEBUG_OBJECTS is not set
808# CONFIG_SLUB_DEBUG_ON is not set
809# CONFIG_SLUB_STATS is not set
810# CONFIG_DEBUG_KMEMLEAK is not set
811CONFIG_DEBUG_RT_MUTEXES=y
812CONFIG_DEBUG_PI_LIST=y
813# CONFIG_RT_MUTEX_TESTER is not set
814CONFIG_DEBUG_SPINLOCK=y
815CONFIG_DEBUG_MUTEXES=y
816# CONFIG_DEBUG_LOCK_ALLOC is not set
817# CONFIG_PROVE_LOCKING is not set
818# CONFIG_LOCK_STAT is not set
819CONFIG_DEBUG_SPINLOCK_SLEEP=y
820# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
821# CONFIG_DEBUG_KOBJECT is not set
822CONFIG_DEBUG_BUGVERBOSE=y
823CONFIG_DEBUG_INFO=y
824# CONFIG_DEBUG_VM is not set
825# CONFIG_DEBUG_WRITECOUNT is not set
826CONFIG_DEBUG_MEMORY_INIT=y
827# CONFIG_DEBUG_LIST is not set
828# CONFIG_DEBUG_SG is not set
829# CONFIG_DEBUG_NOTIFIERS is not set
830# CONFIG_BOOT_PRINTK_DELAY is not set
831# CONFIG_RCU_TORTURE_TEST is not set
832# CONFIG_RCU_CPU_STALL_DETECTOR is not set
833# CONFIG_BACKTRACE_SELF_TEST is not set
834# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
835# CONFIG_FAULT_INJECTION is not set
836# CONFIG_LATENCYTOP is not set
837CONFIG_SYSCTL_SYSCALL_CHECK=y
838# CONFIG_PAGE_POISONING is not set
839CONFIG_HAVE_FUNCTION_TRACER=y
840CONFIG_TRACING_SUPPORT=y
841CONFIG_FTRACE=y
842# CONFIG_FUNCTION_TRACER is not set
843# CONFIG_SCHED_TRACER is not set
844# CONFIG_ENABLE_DEFAULT_TRACERS is not set
845# CONFIG_BOOT_TRACER is not set
846CONFIG_BRANCH_PROFILE_NONE=y
847# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
848# CONFIG_PROFILE_ALL_BRANCHES is not set
849# CONFIG_STACK_TRACER is not set
850# CONFIG_KMEMTRACE is not set
851# CONFIG_WORKQUEUE_TRACER is not set
852# CONFIG_BLK_DEV_IO_TRACE is not set
853# CONFIG_SAMPLES is not set
854CONFIG_HAVE_ARCH_KGDB=y
855# CONFIG_KGDB is not set
856CONFIG_ARM_UNWIND=y
857CONFIG_DEBUG_USER=y
858CONFIG_DEBUG_ERRORS=y
859# CONFIG_DEBUG_STACK_USAGE is not set
860CONFIG_DEBUG_LL=y
861# CONFIG_DEBUG_ICEDCC is not set
862CONFIG_DEBUG_S3C_PORT=y
863CONFIG_DEBUG_S3C_UART=0
864
865#
866# Security options
867#
868# CONFIG_KEYS is not set
869# CONFIG_SECURITY is not set
870# CONFIG_SECURITYFS is not set
871# CONFIG_SECURITY_FILE_CAPABILITIES is not set
872# CONFIG_CRYPTO is not set
873# CONFIG_BINARY_PRINTF is not set
874
875#
876# Library routines
877#
878CONFIG_BITREVERSE=y
879CONFIG_GENERIC_FIND_LAST_BIT=y
880# CONFIG_CRC_CCITT is not set
881# CONFIG_CRC16 is not set
882# CONFIG_CRC_T10DIF is not set
883# CONFIG_CRC_ITU_T is not set
884CONFIG_CRC32=y
885# CONFIG_CRC7 is not set
886# CONFIG_LIBCRC32C is not set
887CONFIG_ZLIB_INFLATE=y
888CONFIG_DECOMPRESS_GZIP=y
889CONFIG_DECOMPRESS_BZIP2=y
890CONFIG_DECOMPRESS_LZMA=y
891CONFIG_HAS_IOMEM=y
892CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 15f8a092b700..00f46d9ce299 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -74,23 +74,56 @@
74 * Enable and disable interrupts 74 * Enable and disable interrupts
75 */ 75 */
76#if __LINUX_ARM_ARCH__ >= 6 76#if __LINUX_ARM_ARCH__ >= 6
77 .macro disable_irq 77 .macro disable_irq_notrace
78 cpsid i 78 cpsid i
79 .endm 79 .endm
80 80
81 .macro enable_irq 81 .macro enable_irq_notrace
82 cpsie i 82 cpsie i
83 .endm 83 .endm
84#else 84#else
85 .macro disable_irq 85 .macro disable_irq_notrace
86 msr cpsr_c, #PSR_I_BIT | SVC_MODE 86 msr cpsr_c, #PSR_I_BIT | SVC_MODE
87 .endm 87 .endm
88 88
89 .macro enable_irq 89 .macro enable_irq_notrace
90 msr cpsr_c, #SVC_MODE 90 msr cpsr_c, #SVC_MODE
91 .endm 91 .endm
92#endif 92#endif
93 93
94 .macro asm_trace_hardirqs_off
95#if defined(CONFIG_TRACE_IRQFLAGS)
96 stmdb sp!, {r0-r3, ip, lr}
97 bl trace_hardirqs_off
98 ldmia sp!, {r0-r3, ip, lr}
99#endif
100 .endm
101
102 .macro asm_trace_hardirqs_on_cond, cond
103#if defined(CONFIG_TRACE_IRQFLAGS)
104 /*
105 * actually the registers should be pushed and pop'd conditionally, but
106 * after bl the flags are certainly clobbered
107 */
108 stmdb sp!, {r0-r3, ip, lr}
109 bl\cond trace_hardirqs_on
110 ldmia sp!, {r0-r3, ip, lr}
111#endif
112 .endm
113
114 .macro asm_trace_hardirqs_on
115 asm_trace_hardirqs_on_cond al
116 .endm
117
118 .macro disable_irq
119 disable_irq_notrace
120 asm_trace_hardirqs_off
121 .endm
122
123 .macro enable_irq
124 asm_trace_hardirqs_on
125 enable_irq_notrace
126 .endm
94/* 127/*
95 * Save the current IRQ state and disable IRQs. Note that this macro 128 * Save the current IRQ state and disable IRQs. Note that this macro
96 * assumes FIQs are enabled, and that the processor is in SVC mode. 129 * assumes FIQs are enabled, and that the processor is in SVC mode.
@@ -104,10 +137,16 @@
104 * Restore interrupt state previously stored in a register. We don't 137 * Restore interrupt state previously stored in a register. We don't
105 * guarantee that this will preserve the flags. 138 * guarantee that this will preserve the flags.
106 */ 139 */
107 .macro restore_irqs, oldcpsr 140 .macro restore_irqs_notrace, oldcpsr
108 msr cpsr_c, \oldcpsr 141 msr cpsr_c, \oldcpsr
109 .endm 142 .endm
110 143
144 .macro restore_irqs, oldcpsr
145 tst \oldcpsr, #PSR_I_BIT
146 asm_trace_hardirqs_on_cond eq
147 restore_irqs_notrace \oldcpsr
148 .endm
149
111#define USER(x...) \ 150#define USER(x...) \
1129999: x; \ 1519999: x; \
113 .section __ex_table,"a"; \ 152 .section __ex_table,"a"; \
@@ -127,3 +166,87 @@
127#endif 166#endif
128#endif 167#endif
129 .endm 168 .endm
169
170#ifdef CONFIG_THUMB2_KERNEL
171 .macro setmode, mode, reg
172 mov \reg, #\mode
173 msr cpsr_c, \reg
174 .endm
175#else
176 .macro setmode, mode, reg
177 msr cpsr_c, #\mode
178 .endm
179#endif
180
181/*
182 * STRT/LDRT access macros with ARM and Thumb-2 variants
183 */
184#ifdef CONFIG_THUMB2_KERNEL
185
186 .macro usraccoff, instr, reg, ptr, inc, off, cond, abort
1879999:
188 .if \inc == 1
189 \instr\cond\()bt \reg, [\ptr, #\off]
190 .elseif \inc == 4
191 \instr\cond\()t \reg, [\ptr, #\off]
192 .else
193 .error "Unsupported inc macro argument"
194 .endif
195
196 .section __ex_table,"a"
197 .align 3
198 .long 9999b, \abort
199 .previous
200 .endm
201
202 .macro usracc, instr, reg, ptr, inc, cond, rept, abort
203 @ explicit IT instruction needed because of the label
204 @ introduced by the USER macro
205 .ifnc \cond,al
206 .if \rept == 1
207 itt \cond
208 .elseif \rept == 2
209 ittt \cond
210 .else
211 .error "Unsupported rept macro argument"
212 .endif
213 .endif
214
215 @ Slightly optimised to avoid incrementing the pointer twice
216 usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
217 .if \rept == 2
218 usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort
219 .endif
220
221 add\cond \ptr, #\rept * \inc
222 .endm
223
224#else /* !CONFIG_THUMB2_KERNEL */
225
226 .macro usracc, instr, reg, ptr, inc, cond, rept, abort
227 .rept \rept
2289999:
229 .if \inc == 1
230 \instr\cond\()bt \reg, [\ptr], #\inc
231 .elseif \inc == 4
232 \instr\cond\()t \reg, [\ptr], #\inc
233 .else
234 .error "Unsupported inc macro argument"
235 .endif
236
237 .section __ex_table,"a"
238 .align 3
239 .long 9999b, \abort
240 .previous
241 .endr
242 .endm
243
244#endif /* CONFIG_THUMB2_KERNEL */
245
246 .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
247 usracc str, \reg, \ptr, \inc, \cond, \rept, \abort
248 .endm
249
250 .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
251 usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
252 .endm
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index c61642b40603..9f390ce335cb 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -12,4 +12,7 @@ struct dev_archdata {
12#endif 12#endif
13}; 13};
14 14
15struct pdev_archdata {
16};
17
15#endif 18#endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index c207504de84d..c3b911ee9151 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -55,6 +55,9 @@ typedef struct user_fp elf_fpregset_t;
55#define R_ARM_MOVW_ABS_NC 43 55#define R_ARM_MOVW_ABS_NC 43
56#define R_ARM_MOVT_ABS 44 56#define R_ARM_MOVT_ABS 44
57 57
58#define R_ARM_THM_CALL 10
59#define R_ARM_THM_JUMP24 30
60
58/* 61/*
59 * These are used to set parameters in the core dumps. 62 * These are used to set parameters in the core dumps.
60 */ 63 */
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index 39c8bc1a006a..103f7ee97313 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -7,8 +7,43 @@
7 7
8#ifndef __ASSEMBLY__ 8#ifndef __ASSEMBLY__
9extern void mcount(void); 9extern void mcount(void);
10extern void __gnu_mcount_nc(void);
10#endif 11#endif
11 12
12#endif 13#endif
13 14
15#ifndef __ASSEMBLY__
16
17#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
18/*
19 * return_address uses walk_stackframe to do it's work. If both
20 * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind
21 * information. For this to work in the function tracer many functions would
22 * have to be marked with __notrace. So for now just depend on
23 * !CONFIG_ARM_UNWIND.
24 */
25
26void *return_address(unsigned int);
27
28#else
29
30extern inline void *return_address(unsigned int level)
31{
32 return NULL;
33}
34
35#endif
36
37#define HAVE_ARCH_CALLER_ADDR
38
39#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
40#define CALLER_ADDR1 ((unsigned long)return_address(1))
41#define CALLER_ADDR2 ((unsigned long)return_address(2))
42#define CALLER_ADDR3 ((unsigned long)return_address(3))
43#define CALLER_ADDR4 ((unsigned long)return_address(4))
44#define CALLER_ADDR5 ((unsigned long)return_address(5))
45#define CALLER_ADDR6 ((unsigned long)return_address(6))
46
47#endif /* ifndef __ASSEMBLY__ */
48
14#endif /* _ASM_ARM_FTRACE */ 49#endif /* _ASM_ARM_FTRACE */
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 9ee743b95de8..bfcc15929a7f 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -99,6 +99,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
99 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" 99 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
100 "1: ldrt %0, [%3]\n" 100 "1: ldrt %0, [%3]\n"
101 " teq %0, %1\n" 101 " teq %0, %1\n"
102 " it eq @ explicit IT needed for the 2b label\n"
102 "2: streqt %2, [%3]\n" 103 "2: streqt %2, [%3]\n"
103 "3:\n" 104 "3:\n"
104 " .section __ex_table,\"a\"\n" 105 " .section __ex_table,\"a\"\n"
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 4da332b03144..b490ecc79def 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -10,6 +10,8 @@ struct mmc_platform_data {
10 unsigned int ocr_mask; /* available voltages */ 10 unsigned int ocr_mask; /* available voltages */
11 u32 (*translate_vdd)(struct device *, unsigned int); 11 u32 (*translate_vdd)(struct device *, unsigned int);
12 unsigned int (*status)(struct device *); 12 unsigned int (*status)(struct device *);
13 int gpio_wp;
14 int gpio_cd;
13}; 15};
14 16
15#endif 17#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 85763db87449..cefedf062138 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -44,7 +44,13 @@
44 * The module space lives between the addresses given by TASK_SIZE 44 * The module space lives between the addresses given by TASK_SIZE
45 * and PAGE_OFFSET - it must be within 32MB of the kernel text. 45 * and PAGE_OFFSET - it must be within 32MB of the kernel text.
46 */ 46 */
47#ifndef CONFIG_THUMB2_KERNEL
47#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024) 48#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024)
49#else
50/* smaller range for Thumb-2 symbols relocation (2^24)*/
51#define MODULES_VADDR (PAGE_OFFSET - 8*1024*1024)
52#endif
53
48#if TASK_SIZE > MODULES_VADDR 54#if TASK_SIZE > MODULES_VADDR
49#error Top of user space clashes with start of module space 55#error Top of user space clashes with start of module space
50#endif 56#endif
@@ -212,7 +218,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
212 * 218 *
213 * page_to_pfn(page) convert a struct page * to a PFN number 219 * page_to_pfn(page) convert a struct page * to a PFN number
214 * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * 220 * pfn_to_page(pfn) convert a _valid_ PFN number to struct page *
215 * pfn_valid(pfn) indicates whether a PFN number is valid
216 * 221 *
217 * virt_to_page(k) convert a _valid_ virtual address to struct page * 222 * virt_to_page(k) convert a _valid_ virtual address to struct page *
218 * virt_addr_valid(k) indicates whether a virtual address is valid 223 * virt_addr_valid(k) indicates whether a virtual address is valid
@@ -221,10 +226,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
221 226
222#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET 227#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
223 228
224#ifndef CONFIG_SPARSEMEM
225#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
226#endif
227
228#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 229#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
229#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) 230#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
230 231
@@ -241,18 +242,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
241#define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) 242#define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn)
242#define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) 243#define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT)
243 244
244#define pfn_valid(pfn) \
245 ({ \
246 unsigned int nid = PFN_TO_NID(pfn); \
247 int valid = nid < MAX_NUMNODES; \
248 if (valid) { \
249 pg_data_t *node = NODE_DATA(nid); \
250 valid = (pfn - node->node_start_pfn) < \
251 node->node_spanned_pages; \
252 } \
253 valid; \
254 })
255
256#define virt_to_page(kaddr) \ 245#define virt_to_page(kaddr) \
257 (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) 246 (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
258 247
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 263fed05ea33..bcdb9291ef0c 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -62,8 +62,10 @@ static inline void check_context(struct mm_struct *mm)
62 62
63static inline void check_context(struct mm_struct *mm) 63static inline void check_context(struct mm_struct *mm)
64{ 64{
65#ifdef CONFIG_MMU
65 if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) 66 if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
66 __check_kvm_seq(mm); 67 __check_kvm_seq(mm);
68#endif
67} 69}
68 70
69#define init_new_context(tsk,mm) 0 71#define init_new_context(tsk,mm) 0
diff --git a/arch/arm/include/asm/page-nommu.h b/arch/arm/include/asm/page-nommu.h
index 3574c0deb37f..d1b162a18dcb 100644
--- a/arch/arm/include/asm/page-nommu.h
+++ b/arch/arm/include/asm/page-nommu.h
@@ -43,7 +43,4 @@ typedef unsigned long pgprot_t;
43#define __pmd(x) (x) 43#define __pmd(x) (x)
44#define __pgprot(x) (x) 44#define __pgprot(x) (x)
45 45
46extern unsigned long memory_start;
47extern unsigned long memory_end;
48
49#endif 46#endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 9c746af1bf6e..3a32af4cce30 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -194,6 +194,10 @@ typedef unsigned long pgprot_t;
194 194
195typedef struct page *pgtable_t; 195typedef struct page *pgtable_t;
196 196
197#ifndef CONFIG_SPARSEMEM
198extern int pfn_valid(unsigned long);
199#endif
200
197#include <asm/memory.h> 201#include <asm/memory.h>
198 202
199#endif /* !__ASSEMBLY__ */ 203#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 3dcd64bf1824..b12cc98bbe04 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -36,6 +36,8 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
36#define pgd_alloc(mm) get_pgd_slow(mm) 36#define pgd_alloc(mm) get_pgd_slow(mm)
37#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) 37#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
38 38
39#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
40
39/* 41/*
40 * Allocate one PTE table. 42 * Allocate one PTE table.
41 * 43 *
@@ -57,7 +59,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
57{ 59{
58 pte_t *pte; 60 pte_t *pte;
59 61
60 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 62 pte = (pte_t *)__get_free_page(PGALLOC_GFP);
61 if (pte) { 63 if (pte) {
62 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); 64 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
63 pte += PTRS_PER_PTE; 65 pte += PTRS_PER_PTE;
@@ -71,10 +73,16 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
71{ 73{
72 struct page *pte; 74 struct page *pte;
73 75
74 pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); 76#ifdef CONFIG_HIGHPTE
77 pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
78#else
79 pte = alloc_pages(PGALLOC_GFP, 0);
80#endif
75 if (pte) { 81 if (pte) {
76 void *page = page_address(pte); 82 if (!PageHighMem(pte)) {
77 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); 83 void *page = page_address(pte);
84 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
85 }
78 pgtable_page_ctor(pte); 86 pgtable_page_ctor(pte);
79 } 87 }
80 88
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index c433c6c73112..201ccaa11f61 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -162,10 +162,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
162 * entries are stored 1024 bytes below. 162 * entries are stored 1024 bytes below.
163 */ 163 */
164#define L_PTE_PRESENT (1 << 0) 164#define L_PTE_PRESENT (1 << 0)
165#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
166#define L_PTE_YOUNG (1 << 1) 165#define L_PTE_YOUNG (1 << 1)
167#define L_PTE_BUFFERABLE (1 << 2) /* obsolete, matches PTE */ 166#define L_PTE_FILE (1 << 2) /* only when !PRESENT */
168#define L_PTE_CACHEABLE (1 << 3) /* obsolete, matches PTE */
169#define L_PTE_DIRTY (1 << 6) 167#define L_PTE_DIRTY (1 << 6)
170#define L_PTE_WRITE (1 << 7) 168#define L_PTE_WRITE (1 << 7)
171#define L_PTE_USER (1 << 8) 169#define L_PTE_USER (1 << 8)
@@ -264,10 +262,19 @@ extern struct page *empty_zero_page;
264#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) 262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
265#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) 263#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
266#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
267#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 265
268#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 266#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr))
269#define pte_unmap(pte) do { } while (0) 267#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
270#define pte_unmap_nested(pte) do { } while (0) 268#define pte_unmap(pte) __pte_unmap(pte, KM_PTE0)
269#define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1)
270
271#ifndef CONFIG_HIGHPTE
272#define __pte_map(dir,km) pmd_page_vaddr(*(dir))
273#define __pte_unmap(pte,km) do { } while (0)
274#else
275#define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
276#define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km)
277#endif
271 278
272#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 279#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
273 280
@@ -381,13 +388,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
381 * 388 *
382 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 389 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
383 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 390 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
384 * <--------------- offset --------------------> <--- type --> 0 0 391 * <--------------- offset --------------------> <- type --> 0 0 0
385 * 392 *
386 * This gives us up to 127 swap files and 32GB per swap file. Note that 393 * This gives us up to 63 swap files and 32GB per swap file. Note that
387 * the offset field is always non-zero. 394 * the offset field is always non-zero.
388 */ 395 */
389#define __SWP_TYPE_SHIFT 2 396#define __SWP_TYPE_SHIFT 3
390#define __SWP_TYPE_BITS 7 397#define __SWP_TYPE_BITS 6
391#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) 398#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
392#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) 399#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
393 400
@@ -411,13 +418,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
411 * 418 *
412 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 419 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
413 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 420 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
414 * <------------------------ offset -------------------------> 1 0 421 * <----------------------- offset ------------------------> 1 0 0
415 */ 422 */
416#define pte_file(pte) (pte_val(pte) & L_PTE_FILE) 423#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
417#define pte_to_pgoff(x) (pte_val(x) >> 2) 424#define pte_to_pgoff(x) (pte_val(x) >> 3)
418#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) 425#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE)
419 426
420#define PTE_FILE_MAX_BITS 30 427#define PTE_FILE_MAX_BITS 29
421 428
422/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ 429/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
423/* FIXME: this is not correct */ 430/* FIXME: this is not correct */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 67b833c9b6b9..bbecccda76d0 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -82,6 +82,14 @@
82#define PSR_ENDSTATE 0 82#define PSR_ENDSTATE 0
83#endif 83#endif
84 84
85/*
86 * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
87 * process is located in memory.
88 */
89#define PT_TEXT_ADDR 0x10000
90#define PT_DATA_ADDR 0x10004
91#define PT_TEXT_END_ADDR 0x10008
92
85#ifndef __ASSEMBLY__ 93#ifndef __ASSEMBLY__
86 94
87/* 95/*
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index 537de4e0ef50..92ac61d294fd 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -57,4 +57,7 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* _ASM_SOCKET_H */ 63#endif /* _ASM_SOCKET_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 73394e50cbca..2dfb7d7a66e9 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -130,23 +130,28 @@ extern void vfp_sync_state(struct thread_info *thread);
130 * TIF_SYSCALL_TRACE - syscall trace active 130 * TIF_SYSCALL_TRACE - syscall trace active
131 * TIF_SIGPENDING - signal pending 131 * TIF_SIGPENDING - signal pending
132 * TIF_NEED_RESCHED - rescheduling necessary 132 * TIF_NEED_RESCHED - rescheduling necessary
133 * TIF_NOTIFY_RESUME - callback before returning to user
133 * TIF_USEDFPU - FPU was used by this task this quantum (SMP) 134 * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
134 * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED 135 * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
135 */ 136 */
136#define TIF_SIGPENDING 0 137#define TIF_SIGPENDING 0
137#define TIF_NEED_RESCHED 1 138#define TIF_NEED_RESCHED 1
139#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
138#define TIF_SYSCALL_TRACE 8 140#define TIF_SYSCALL_TRACE 8
139#define TIF_POLLING_NRFLAG 16 141#define TIF_POLLING_NRFLAG 16
140#define TIF_USING_IWMMXT 17 142#define TIF_USING_IWMMXT 17
141#define TIF_MEMDIE 18 143#define TIF_MEMDIE 18
142#define TIF_FREEZE 19 144#define TIF_FREEZE 19
145#define TIF_RESTORE_SIGMASK 20
143 146
144#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 147#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
145#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 148#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
149#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
146#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 150#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
147#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 151#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
148#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) 152#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
149#define _TIF_FREEZE (1 << TIF_FREEZE) 153#define _TIF_FREEZE (1 << TIF_FREEZE)
154#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
150 155
151/* 156/*
152 * Change these and you break ASM code in entry-common.S 157 * Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 0da9bc9b3b1d..1d6bd40a4322 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -17,6 +17,7 @@
17#include <asm/memory.h> 17#include <asm/memory.h>
18#include <asm/domain.h> 18#include <asm/domain.h>
19#include <asm/system.h> 19#include <asm/system.h>
20#include <asm/unified.h>
20 21
21#define VERIFY_READ 0 22#define VERIFY_READ 0
22#define VERIFY_WRITE 1 23#define VERIFY_WRITE 1
@@ -365,8 +366,10 @@ do { \
365 366
366#define __put_user_asm_dword(x,__pu_addr,err) \ 367#define __put_user_asm_dword(x,__pu_addr,err) \
367 __asm__ __volatile__( \ 368 __asm__ __volatile__( \
368 "1: strt " __reg_oper1 ", [%1], #4\n" \ 369 ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \
369 "2: strt " __reg_oper0 ", [%1]\n" \ 370 ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \
371 THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \
372 THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \
370 "3:\n" \ 373 "3:\n" \
371 " .section .fixup,\"ax\"\n" \ 374 " .section .fixup,\"ax\"\n" \
372 " .align 2\n" \ 375 " .align 2\n" \
diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h
new file mode 100644
index 000000000000..073e85b9b961
--- /dev/null
+++ b/arch/arm/include/asm/unified.h
@@ -0,0 +1,126 @@
1/*
2 * include/asm-arm/unified.h - Unified Assembler Syntax helper macros
3 *
4 * Copyright (C) 2008 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef __ASM_UNIFIED_H
21#define __ASM_UNIFIED_H
22
23#if defined(__ASSEMBLY__) && defined(CONFIG_ARM_ASM_UNIFIED)
24 .syntax unified
25#endif
26
27#ifdef CONFIG_THUMB2_KERNEL
28
29#if __GNUC__ < 4
30#error Thumb-2 kernel requires gcc >= 4
31#endif
32
33/* The CPSR bit describing the instruction set (Thumb) */
34#define PSR_ISETSTATE PSR_T_BIT
35
36#define ARM(x...)
37#define THUMB(x...) x
38#define W(instr) instr.w
39#define BSYM(sym) sym + 1
40
41#else /* !CONFIG_THUMB2_KERNEL */
42
43/* The CPSR bit describing the instruction set (ARM) */
44#define PSR_ISETSTATE 0
45
46#define ARM(x...) x
47#define THUMB(x...)
48#define W(instr) instr
49#define BSYM(sym) sym
50
51#endif /* CONFIG_THUMB2_KERNEL */
52
53#ifndef CONFIG_ARM_ASM_UNIFIED
54
55/*
56 * If the unified assembly syntax isn't used (in ARM mode), these
57 * macros expand to an empty string
58 */
59#ifdef __ASSEMBLY__
60 .macro it, cond
61 .endm
62 .macro itt, cond
63 .endm
64 .macro ite, cond
65 .endm
66 .macro ittt, cond
67 .endm
68 .macro itte, cond
69 .endm
70 .macro itet, cond
71 .endm
72 .macro itee, cond
73 .endm
74 .macro itttt, cond
75 .endm
76 .macro ittte, cond
77 .endm
78 .macro ittet, cond
79 .endm
80 .macro ittee, cond
81 .endm
82 .macro itett, cond
83 .endm
84 .macro itete, cond
85 .endm
86 .macro iteet, cond
87 .endm
88 .macro iteee, cond
89 .endm
90#else /* !__ASSEMBLY__ */
91__asm__(
92" .macro it, cond\n"
93" .endm\n"
94" .macro itt, cond\n"
95" .endm\n"
96" .macro ite, cond\n"
97" .endm\n"
98" .macro ittt, cond\n"
99" .endm\n"
100" .macro itte, cond\n"
101" .endm\n"
102" .macro itet, cond\n"
103" .endm\n"
104" .macro itee, cond\n"
105" .endm\n"
106" .macro itttt, cond\n"
107" .endm\n"
108" .macro ittte, cond\n"
109" .endm\n"
110" .macro ittet, cond\n"
111" .endm\n"
112" .macro ittee, cond\n"
113" .endm\n"
114" .macro itett, cond\n"
115" .endm\n"
116" .macro itete, cond\n"
117" .endm\n"
118" .macro iteet, cond\n"
119" .endm\n"
120" .macro iteee, cond\n"
121" .endm\n");
122#endif /* __ASSEMBLY__ */
123
124#endif /* CONFIG_ARM_ASM_UNIFIED */
125
126#endif /* !__ASM_UNIFIED_H */
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 0e97b8cb77d5..9122c9ee18fb 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -360,8 +360,8 @@
360#define __NR_readlinkat (__NR_SYSCALL_BASE+332) 360#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
361#define __NR_fchmodat (__NR_SYSCALL_BASE+333) 361#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
362#define __NR_faccessat (__NR_SYSCALL_BASE+334) 362#define __NR_faccessat (__NR_SYSCALL_BASE+334)
363 /* 335 for pselect6 */ 363#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
364 /* 336 for ppoll */ 364#define __NR_ppoll (__NR_SYSCALL_BASE+336)
365#define __NR_unshare (__NR_SYSCALL_BASE+337) 365#define __NR_unshare (__NR_SYSCALL_BASE+337)
366#define __NR_set_robust_list (__NR_SYSCALL_BASE+338) 366#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
367#define __NR_get_robust_list (__NR_SYSCALL_BASE+339) 367#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
@@ -372,7 +372,7 @@
372#define __NR_vmsplice (__NR_SYSCALL_BASE+343) 372#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
373#define __NR_move_pages (__NR_SYSCALL_BASE+344) 373#define __NR_move_pages (__NR_SYSCALL_BASE+344)
374#define __NR_getcpu (__NR_SYSCALL_BASE+345) 374#define __NR_getcpu (__NR_SYSCALL_BASE+345)
375 /* 346 for epoll_pwait */ 375#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
376#define __NR_kexec_load (__NR_SYSCALL_BASE+347) 376#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
377#define __NR_utimensat (__NR_SYSCALL_BASE+348) 377#define __NR_utimensat (__NR_SYSCALL_BASE+348)
378#define __NR_signalfd (__NR_SYSCALL_BASE+349) 378#define __NR_signalfd (__NR_SYSCALL_BASE+349)
@@ -432,6 +432,7 @@
432#define __ARCH_WANT_SYS_SIGPENDING 432#define __ARCH_WANT_SYS_SIGPENDING
433#define __ARCH_WANT_SYS_SIGPROCMASK 433#define __ARCH_WANT_SYS_SIGPROCMASK
434#define __ARCH_WANT_SYS_RT_SIGACTION 434#define __ARCH_WANT_SYS_RT_SIGACTION
435#define __ARCH_WANT_SYS_RT_SIGSUSPEND
435 436
436#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) 437#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
437#define __ARCH_WANT_SYS_TIME 438#define __ARCH_WANT_SYS_TIME
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ff89d0b3abc5..3213c9382b17 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -8,10 +8,12 @@ ifdef CONFIG_DYNAMIC_FTRACE
8CFLAGS_REMOVE_ftrace.o = -pg 8CFLAGS_REMOVE_ftrace.o = -pg
9endif 9endif
10 10
11CFLAGS_REMOVE_return_address.o = -pg
12
11# Object file lists. 13# Object file lists.
12 14
13obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ 15obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \
14 process.o ptrace.o setup.o signal.o \ 16 process.o ptrace.o return_address.o setup.o signal.o \
15 sys_arm.o stacktrace.o time.o traps.o 17 sys_arm.o stacktrace.o time.o traps.o
16 18
17obj-$(CONFIG_ISA_DMA_API) += dma.o 19obj-$(CONFIG_ISA_DMA_API) += dma.o
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 531e1860e546..0e627705f746 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -186,4 +186,5 @@ EXPORT_SYMBOL(_find_next_bit_be);
186 186
187#ifdef CONFIG_FUNCTION_TRACER 187#ifdef CONFIG_FUNCTION_TRACER
188EXPORT_SYMBOL(mcount); 188EXPORT_SYMBOL(mcount);
189EXPORT_SYMBOL(__gnu_mcount_nc);
189#endif 190#endif
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index f776e72a4cb8..ecfa98954d1d 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -81,7 +81,7 @@
81 CALL(sys_ni_syscall) /* was sys_ssetmask */ 81 CALL(sys_ni_syscall) /* was sys_ssetmask */
82/* 70 */ CALL(sys_setreuid16) 82/* 70 */ CALL(sys_setreuid16)
83 CALL(sys_setregid16) 83 CALL(sys_setregid16)
84 CALL(sys_sigsuspend_wrapper) 84 CALL(sys_sigsuspend)
85 CALL(sys_sigpending) 85 CALL(sys_sigpending)
86 CALL(sys_sethostname) 86 CALL(sys_sethostname)
87/* 75 */ CALL(sys_setrlimit) 87/* 75 */ CALL(sys_setrlimit)
@@ -188,7 +188,7 @@
188 CALL(sys_rt_sigpending) 188 CALL(sys_rt_sigpending)
189 CALL(sys_rt_sigtimedwait) 189 CALL(sys_rt_sigtimedwait)
190 CALL(sys_rt_sigqueueinfo) 190 CALL(sys_rt_sigqueueinfo)
191 CALL(sys_rt_sigsuspend_wrapper) 191 CALL(sys_rt_sigsuspend)
192/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) 192/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
193 CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) 193 CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
194 CALL(sys_chown16) 194 CALL(sys_chown16)
@@ -344,8 +344,8 @@
344 CALL(sys_readlinkat) 344 CALL(sys_readlinkat)
345 CALL(sys_fchmodat) 345 CALL(sys_fchmodat)
346 CALL(sys_faccessat) 346 CALL(sys_faccessat)
347/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ 347/* 335 */ CALL(sys_pselect6)
348 CALL(sys_ni_syscall) /* eventually ppoll */ 348 CALL(sys_ppoll)
349 CALL(sys_unshare) 349 CALL(sys_unshare)
350 CALL(sys_set_robust_list) 350 CALL(sys_set_robust_list)
351 CALL(sys_get_robust_list) 351 CALL(sys_get_robust_list)
@@ -355,7 +355,7 @@
355 CALL(sys_vmsplice) 355 CALL(sys_vmsplice)
356 CALL(sys_move_pages) 356 CALL(sys_move_pages)
357/* 345 */ CALL(sys_getcpu) 357/* 345 */ CALL(sys_getcpu)
358 CALL(sys_ni_syscall) /* eventually epoll_pwait */ 358 CALL(sys_epoll_pwait)
359 CALL(sys_kexec_load) 359 CALL(sys_kexec_load)
360 CALL(sys_utimensat) 360 CALL(sys_utimensat)
361 CALL(sys_signalfd) 361 CALL(sys_signalfd)
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index 99995c2b2312..769abe15cf91 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread)
31 31
32static int crunch_enabled(u32 devcfg) 32static int crunch_enabled(u32 devcfg)
33{ 33{
34 return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); 34 return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
35} 35}
36 36
37static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) 37static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
@@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
56 break; 56 break;
57 57
58 case THREAD_NOTIFY_SWITCH: 58 case THREAD_NOTIFY_SWITCH:
59 devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); 59 devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
60 if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { 60 if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
61 devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; 61 /*
62 * We don't use ep93xx_syscon_swlocked_write() here
63 * because we are on the context switch path and
64 * preemption is already disabled.
65 */
66 devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
62 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 67 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
63 __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); 68 __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
64 } 69 }
65 break; 70 break;
66 } 71 }
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index fc8af43c5000..3d727a8a23bc 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -34,7 +34,7 @@
34 @ 34 @
35 @ routine called with r0 = irq number, r1 = struct pt_regs * 35 @ routine called with r0 = irq number, r1 = struct pt_regs *
36 @ 36 @
37 adrne lr, 1b 37 adrne lr, BSYM(1b)
38 bne asm_do_IRQ 38 bne asm_do_IRQ
39 39
40#ifdef CONFIG_SMP 40#ifdef CONFIG_SMP
@@ -46,13 +46,13 @@
46 */ 46 */
47 test_for_ipi r0, r6, r5, lr 47 test_for_ipi r0, r6, r5, lr
48 movne r0, sp 48 movne r0, sp
49 adrne lr, 1b 49 adrne lr, BSYM(1b)
50 bne do_IPI 50 bne do_IPI
51 51
52#ifdef CONFIG_LOCAL_TIMERS 52#ifdef CONFIG_LOCAL_TIMERS
53 test_for_ltirq r0, r6, r5, lr 53 test_for_ltirq r0, r6, r5, lr
54 movne r0, sp 54 movne r0, sp
55 adrne lr, 1b 55 adrne lr, BSYM(1b)
56 bne do_local_timer 56 bne do_local_timer
57#endif 57#endif
58#endif 58#endif
@@ -70,7 +70,10 @@
70 */ 70 */
71 .macro inv_entry, reason 71 .macro inv_entry, reason
72 sub sp, sp, #S_FRAME_SIZE 72 sub sp, sp, #S_FRAME_SIZE
73 stmib sp, {r1 - lr} 73 ARM( stmib sp, {r1 - lr} )
74 THUMB( stmia sp, {r0 - r12} )
75 THUMB( str sp, [sp, #S_SP] )
76 THUMB( str lr, [sp, #S_LR] )
74 mov r1, #\reason 77 mov r1, #\reason
75 .endm 78 .endm
76 79
@@ -126,17 +129,24 @@ ENDPROC(__und_invalid)
126 .macro svc_entry, stack_hole=0 129 .macro svc_entry, stack_hole=0
127 UNWIND(.fnstart ) 130 UNWIND(.fnstart )
128 UNWIND(.save {r0 - pc} ) 131 UNWIND(.save {r0 - pc} )
129 sub sp, sp, #(S_FRAME_SIZE + \stack_hole) 132 sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
133#ifdef CONFIG_THUMB2_KERNEL
134 SPFIX( str r0, [sp] ) @ temporarily saved
135 SPFIX( mov r0, sp )
136 SPFIX( tst r0, #4 ) @ test original stack alignment
137 SPFIX( ldr r0, [sp] ) @ restored
138#else
130 SPFIX( tst sp, #4 ) 139 SPFIX( tst sp, #4 )
131 SPFIX( bicne sp, sp, #4 ) 140#endif
132 stmib sp, {r1 - r12} 141 SPFIX( subeq sp, sp, #4 )
142 stmia sp, {r1 - r12}
133 143
134 ldmia r0, {r1 - r3} 144 ldmia r0, {r1 - r3}
135 add r5, sp, #S_SP @ here for interlock avoidance 145 add r5, sp, #S_SP - 4 @ here for interlock avoidance
136 mov r4, #-1 @ "" "" "" "" 146 mov r4, #-1 @ "" "" "" ""
137 add r0, sp, #(S_FRAME_SIZE + \stack_hole) 147 add r0, sp, #(S_FRAME_SIZE + \stack_hole - 4)
138 SPFIX( addne r0, r0, #4 ) 148 SPFIX( addeq r0, r0, #4 )
139 str r1, [sp] @ save the "real" r0 copied 149 str r1, [sp, #-4]! @ save the "real" r0 copied
140 @ from the exception stack 150 @ from the exception stack
141 151
142 mov r1, lr 152 mov r1, lr
@@ -151,6 +161,8 @@ ENDPROC(__und_invalid)
151 @ r4 - orig_r0 (see pt_regs definition in ptrace.h) 161 @ r4 - orig_r0 (see pt_regs definition in ptrace.h)
152 @ 162 @
153 stmia r5, {r0 - r4} 163 stmia r5, {r0 - r4}
164
165 asm_trace_hardirqs_off
154 .endm 166 .endm
155 167
156 .align 5 168 .align 5
@@ -196,9 +208,8 @@ __dabt_svc:
196 @ 208 @
197 @ restore SPSR and restart the instruction 209 @ restore SPSR and restart the instruction
198 @ 210 @
199 ldr r0, [sp, #S_PSR] 211 ldr r2, [sp, #S_PSR]
200 msr spsr_cxsf, r0 212 svc_exit r2 @ return from exception
201 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
202 UNWIND(.fnend ) 213 UNWIND(.fnend )
203ENDPROC(__dabt_svc) 214ENDPROC(__dabt_svc)
204 215
@@ -206,9 +217,6 @@ ENDPROC(__dabt_svc)
206__irq_svc: 217__irq_svc:
207 svc_entry 218 svc_entry
208 219
209#ifdef CONFIG_TRACE_IRQFLAGS
210 bl trace_hardirqs_off
211#endif
212#ifdef CONFIG_PREEMPT 220#ifdef CONFIG_PREEMPT
213 get_thread_info tsk 221 get_thread_info tsk
214 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 222 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -225,13 +233,12 @@ __irq_svc:
225 tst r0, #_TIF_NEED_RESCHED 233 tst r0, #_TIF_NEED_RESCHED
226 blne svc_preempt 234 blne svc_preempt
227#endif 235#endif
228 ldr r0, [sp, #S_PSR] @ irqs are already disabled 236 ldr r4, [sp, #S_PSR] @ irqs are already disabled
229 msr spsr_cxsf, r0
230#ifdef CONFIG_TRACE_IRQFLAGS 237#ifdef CONFIG_TRACE_IRQFLAGS
231 tst r0, #PSR_I_BIT 238 tst r4, #PSR_I_BIT
232 bleq trace_hardirqs_on 239 bleq trace_hardirqs_on
233#endif 240#endif
234 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 241 svc_exit r4 @ return from exception
235 UNWIND(.fnend ) 242 UNWIND(.fnend )
236ENDPROC(__irq_svc) 243ENDPROC(__irq_svc)
237 244
@@ -266,7 +273,7 @@ __und_svc:
266 @ r0 - instruction 273 @ r0 - instruction
267 @ 274 @
268 ldr r0, [r2, #-4] 275 ldr r0, [r2, #-4]
269 adr r9, 1f 276 adr r9, BSYM(1f)
270 bl call_fpe 277 bl call_fpe
271 278
272 mov r0, sp @ struct pt_regs *regs 279 mov r0, sp @ struct pt_regs *regs
@@ -280,9 +287,8 @@ __und_svc:
280 @ 287 @
281 @ restore SPSR and restart the instruction 288 @ restore SPSR and restart the instruction
282 @ 289 @
283 ldr lr, [sp, #S_PSR] @ Get SVC cpsr 290 ldr r2, [sp, #S_PSR] @ Get SVC cpsr
284 msr spsr_cxsf, lr 291 svc_exit r2 @ return from exception
285 ldmia sp, {r0 - pc}^ @ Restore SVC registers
286 UNWIND(.fnend ) 292 UNWIND(.fnend )
287ENDPROC(__und_svc) 293ENDPROC(__und_svc)
288 294
@@ -323,9 +329,8 @@ __pabt_svc:
323 @ 329 @
324 @ restore SPSR and restart the instruction 330 @ restore SPSR and restart the instruction
325 @ 331 @
326 ldr r0, [sp, #S_PSR] 332 ldr r2, [sp, #S_PSR]
327 msr spsr_cxsf, r0 333 svc_exit r2 @ return from exception
328 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
329 UNWIND(.fnend ) 334 UNWIND(.fnend )
330ENDPROC(__pabt_svc) 335ENDPROC(__pabt_svc)
331 336
@@ -353,7 +358,8 @@ ENDPROC(__pabt_svc)
353 UNWIND(.fnstart ) 358 UNWIND(.fnstart )
354 UNWIND(.cantunwind ) @ don't unwind the user space 359 UNWIND(.cantunwind ) @ don't unwind the user space
355 sub sp, sp, #S_FRAME_SIZE 360 sub sp, sp, #S_FRAME_SIZE
356 stmib sp, {r1 - r12} 361 ARM( stmib sp, {r1 - r12} )
362 THUMB( stmia sp, {r0 - r12} )
357 363
358 ldmia r0, {r1 - r3} 364 ldmia r0, {r1 - r3}
359 add r0, sp, #S_PC @ here for interlock avoidance 365 add r0, sp, #S_PC @ here for interlock avoidance
@@ -372,7 +378,8 @@ ENDPROC(__pabt_svc)
372 @ Also, separately save sp_usr and lr_usr 378 @ Also, separately save sp_usr and lr_usr
373 @ 379 @
374 stmia r0, {r2 - r4} 380 stmia r0, {r2 - r4}
375 stmdb r0, {sp, lr}^ 381 ARM( stmdb r0, {sp, lr}^ )
382 THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
376 383
377 @ 384 @
378 @ Enable the alignment trap while in kernel mode 385 @ Enable the alignment trap while in kernel mode
@@ -383,6 +390,8 @@ ENDPROC(__pabt_svc)
383 @ Clear FP to mark the first stack frame 390 @ Clear FP to mark the first stack frame
384 @ 391 @
385 zero_fp 392 zero_fp
393
394 asm_trace_hardirqs_off
386 .endm 395 .endm
387 396
388 .macro kuser_cmpxchg_check 397 .macro kuser_cmpxchg_check
@@ -427,7 +436,7 @@ __dabt_usr:
427 @ 436 @
428 enable_irq 437 enable_irq
429 mov r2, sp 438 mov r2, sp
430 adr lr, ret_from_exception 439 adr lr, BSYM(ret_from_exception)
431 b do_DataAbort 440 b do_DataAbort
432 UNWIND(.fnend ) 441 UNWIND(.fnend )
433ENDPROC(__dabt_usr) 442ENDPROC(__dabt_usr)
@@ -437,9 +446,6 @@ __irq_usr:
437 usr_entry 446 usr_entry
438 kuser_cmpxchg_check 447 kuser_cmpxchg_check
439 448
440#ifdef CONFIG_TRACE_IRQFLAGS
441 bl trace_hardirqs_off
442#endif
443 get_thread_info tsk 449 get_thread_info tsk
444#ifdef CONFIG_PREEMPT 450#ifdef CONFIG_PREEMPT
445 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 451 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -452,7 +458,9 @@ __irq_usr:
452 ldr r0, [tsk, #TI_PREEMPT] 458 ldr r0, [tsk, #TI_PREEMPT]
453 str r8, [tsk, #TI_PREEMPT] 459 str r8, [tsk, #TI_PREEMPT]
454 teq r0, r7 460 teq r0, r7
455 strne r0, [r0, -r0] 461 ARM( strne r0, [r0, -r0] )
462 THUMB( movne r0, #0 )
463 THUMB( strne r0, [r0] )
456#endif 464#endif
457#ifdef CONFIG_TRACE_IRQFLAGS 465#ifdef CONFIG_TRACE_IRQFLAGS
458 bl trace_hardirqs_on 466 bl trace_hardirqs_on
@@ -476,9 +484,10 @@ __und_usr:
476 @ 484 @
477 @ r0 - instruction 485 @ r0 - instruction
478 @ 486 @
479 adr r9, ret_from_exception 487 adr r9, BSYM(ret_from_exception)
480 adr lr, __und_usr_unknown 488 adr lr, BSYM(__und_usr_unknown)
481 tst r3, #PSR_T_BIT @ Thumb mode? 489 tst r3, #PSR_T_BIT @ Thumb mode?
490 itet eq @ explicit IT needed for the 1f label
482 subeq r4, r2, #4 @ ARM instr at LR - 4 491 subeq r4, r2, #4 @ ARM instr at LR - 4
483 subne r4, r2, #2 @ Thumb instr at LR - 2 492 subne r4, r2, #2 @ Thumb instr at LR - 2
4841: ldreqt r0, [r4] 4931: ldreqt r0, [r4]
@@ -488,7 +497,10 @@ __und_usr:
488 beq call_fpe 497 beq call_fpe
489 @ Thumb instruction 498 @ Thumb instruction
490#if __LINUX_ARM_ARCH__ >= 7 499#if __LINUX_ARM_ARCH__ >= 7
4912: ldrht r5, [r4], #2 5002:
501 ARM( ldrht r5, [r4], #2 )
502 THUMB( ldrht r5, [r4] )
503 THUMB( add r4, r4, #2 )
492 and r0, r5, #0xf800 @ mask bits 111x x... .... .... 504 and r0, r5, #0xf800 @ mask bits 111x x... .... ....
493 cmp r0, #0xe800 @ 32bit instruction if xx != 0 505 cmp r0, #0xe800 @ 32bit instruction if xx != 0
494 blo __und_usr_unknown 506 blo __und_usr_unknown
@@ -577,9 +589,11 @@ call_fpe:
577 moveq pc, lr 589 moveq pc, lr
578 get_thread_info r10 @ get current thread 590 get_thread_info r10 @ get current thread
579 and r8, r0, #0x00000f00 @ mask out CP number 591 and r8, r0, #0x00000f00 @ mask out CP number
592 THUMB( lsr r8, r8, #8 )
580 mov r7, #1 593 mov r7, #1
581 add r6, r10, #TI_USED_CP 594 add r6, r10, #TI_USED_CP
582 strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[] 595 ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[]
596 THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[]
583#ifdef CONFIG_IWMMXT 597#ifdef CONFIG_IWMMXT
584 @ Test if we need to give access to iWMMXt coprocessors 598 @ Test if we need to give access to iWMMXt coprocessors
585 ldr r5, [r10, #TI_FLAGS] 599 ldr r5, [r10, #TI_FLAGS]
@@ -587,36 +601,38 @@ call_fpe:
587 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) 601 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1)
588 bcs iwmmxt_task_enable 602 bcs iwmmxt_task_enable
589#endif 603#endif
590 add pc, pc, r8, lsr #6 604 ARM( add pc, pc, r8, lsr #6 )
591 mov r0, r0 605 THUMB( lsl r8, r8, #2 )
592 606 THUMB( add pc, r8 )
593 mov pc, lr @ CP#0 607 nop
594 b do_fpe @ CP#1 (FPE) 608
595 b do_fpe @ CP#2 (FPE) 609 W(mov) pc, lr @ CP#0
596 mov pc, lr @ CP#3 610 W(b) do_fpe @ CP#1 (FPE)
611 W(b) do_fpe @ CP#2 (FPE)
612 W(mov) pc, lr @ CP#3
597#ifdef CONFIG_CRUNCH 613#ifdef CONFIG_CRUNCH
598 b crunch_task_enable @ CP#4 (MaverickCrunch) 614 b crunch_task_enable @ CP#4 (MaverickCrunch)
599 b crunch_task_enable @ CP#5 (MaverickCrunch) 615 b crunch_task_enable @ CP#5 (MaverickCrunch)
600 b crunch_task_enable @ CP#6 (MaverickCrunch) 616 b crunch_task_enable @ CP#6 (MaverickCrunch)
601#else 617#else
602 mov pc, lr @ CP#4 618 W(mov) pc, lr @ CP#4
603 mov pc, lr @ CP#5 619 W(mov) pc, lr @ CP#5
604 mov pc, lr @ CP#6 620 W(mov) pc, lr @ CP#6
605#endif 621#endif
606 mov pc, lr @ CP#7 622 W(mov) pc, lr @ CP#7
607 mov pc, lr @ CP#8 623 W(mov) pc, lr @ CP#8
608 mov pc, lr @ CP#9 624 W(mov) pc, lr @ CP#9
609#ifdef CONFIG_VFP 625#ifdef CONFIG_VFP
610 b do_vfp @ CP#10 (VFP) 626 W(b) do_vfp @ CP#10 (VFP)
611 b do_vfp @ CP#11 (VFP) 627 W(b) do_vfp @ CP#11 (VFP)
612#else 628#else
613 mov pc, lr @ CP#10 (VFP) 629 W(mov) pc, lr @ CP#10 (VFP)
614 mov pc, lr @ CP#11 (VFP) 630 W(mov) pc, lr @ CP#11 (VFP)
615#endif 631#endif
616 mov pc, lr @ CP#12 632 W(mov) pc, lr @ CP#12
617 mov pc, lr @ CP#13 633 W(mov) pc, lr @ CP#13
618 mov pc, lr @ CP#14 (Debug) 634 W(mov) pc, lr @ CP#14 (Debug)
619 mov pc, lr @ CP#15 (Control) 635 W(mov) pc, lr @ CP#15 (Control)
620 636
621#ifdef CONFIG_NEON 637#ifdef CONFIG_NEON
622 .align 6 638 .align 6
@@ -667,7 +683,7 @@ no_fp: mov pc, lr
667__und_usr_unknown: 683__und_usr_unknown:
668 enable_irq 684 enable_irq
669 mov r0, sp 685 mov r0, sp
670 adr lr, ret_from_exception 686 adr lr, BSYM(ret_from_exception)
671 b do_undefinstr 687 b do_undefinstr
672ENDPROC(__und_usr_unknown) 688ENDPROC(__und_usr_unknown)
673 689
@@ -711,7 +727,10 @@ ENTRY(__switch_to)
711 UNWIND(.cantunwind ) 727 UNWIND(.cantunwind )
712 add ip, r1, #TI_CPU_SAVE 728 add ip, r1, #TI_CPU_SAVE
713 ldr r3, [r2, #TI_TP_VALUE] 729 ldr r3, [r2, #TI_TP_VALUE]
714 stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack 730 ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack
731 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
732 THUMB( str sp, [ip], #4 )
733 THUMB( str lr, [ip], #4 )
715#ifdef CONFIG_MMU 734#ifdef CONFIG_MMU
716 ldr r6, [r2, #TI_CPU_DOMAIN] 735 ldr r6, [r2, #TI_CPU_DOMAIN]
717#endif 736#endif
@@ -736,8 +755,12 @@ ENTRY(__switch_to)
736 ldr r0, =thread_notify_head 755 ldr r0, =thread_notify_head
737 mov r1, #THREAD_NOTIFY_SWITCH 756 mov r1, #THREAD_NOTIFY_SWITCH
738 bl atomic_notifier_call_chain 757 bl atomic_notifier_call_chain
758 THUMB( mov ip, r4 )
739 mov r0, r5 759 mov r0, r5
740 ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously 760 ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
761 THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously
762 THUMB( ldr sp, [ip], #4 )
763 THUMB( ldr pc, [ip] )
741 UNWIND(.fnend ) 764 UNWIND(.fnend )
742ENDPROC(__switch_to) 765ENDPROC(__switch_to)
743 766
@@ -772,6 +795,7 @@ ENDPROC(__switch_to)
772 * if your compiled code is not going to use the new instructions for other 795 * if your compiled code is not going to use the new instructions for other
773 * purpose. 796 * purpose.
774 */ 797 */
798 THUMB( .arm )
775 799
776 .macro usr_ret, reg 800 .macro usr_ret, reg
777#ifdef CONFIG_ARM_THUMB 801#ifdef CONFIG_ARM_THUMB
@@ -1020,6 +1044,7 @@ __kuser_helper_version: @ 0xffff0ffc
1020 .globl __kuser_helper_end 1044 .globl __kuser_helper_end
1021__kuser_helper_end: 1045__kuser_helper_end:
1022 1046
1047 THUMB( .thumb )
1023 1048
1024/* 1049/*
1025 * Vector stubs. 1050 * Vector stubs.
@@ -1054,17 +1079,23 @@ vector_\name:
1054 @ Prepare for SVC32 mode. IRQs remain disabled. 1079 @ Prepare for SVC32 mode. IRQs remain disabled.
1055 @ 1080 @
1056 mrs r0, cpsr 1081 mrs r0, cpsr
1057 eor r0, r0, #(\mode ^ SVC_MODE) 1082 eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
1058 msr spsr_cxsf, r0 1083 msr spsr_cxsf, r0
1059 1084
1060 @ 1085 @
1061 @ the branch table must immediately follow this code 1086 @ the branch table must immediately follow this code
1062 @ 1087 @
1063 and lr, lr, #0x0f 1088 and lr, lr, #0x0f
1089 THUMB( adr r0, 1f )
1090 THUMB( ldr lr, [r0, lr, lsl #2] )
1064 mov r0, sp 1091 mov r0, sp
1065 ldr lr, [pc, lr, lsl #2] 1092 ARM( ldr lr, [pc, lr, lsl #2] )
1066 movs pc, lr @ branch to handler in SVC mode 1093 movs pc, lr @ branch to handler in SVC mode
1067ENDPROC(vector_\name) 1094ENDPROC(vector_\name)
1095
1096 .align 2
1097 @ handler addresses follow this label
10981:
1068 .endm 1099 .endm
1069 1100
1070 .globl __stubs_start 1101 .globl __stubs_start
@@ -1202,14 +1233,16 @@ __stubs_end:
1202 1233
1203 .globl __vectors_start 1234 .globl __vectors_start
1204__vectors_start: 1235__vectors_start:
1205 swi SYS_ERROR0 1236 ARM( swi SYS_ERROR0 )
1206 b vector_und + stubs_offset 1237 THUMB( svc #0 )
1207 ldr pc, .LCvswi + stubs_offset 1238 THUMB( nop )
1208 b vector_pabt + stubs_offset 1239 W(b) vector_und + stubs_offset
1209 b vector_dabt + stubs_offset 1240 W(ldr) pc, .LCvswi + stubs_offset
1210 b vector_addrexcptn + stubs_offset 1241 W(b) vector_pabt + stubs_offset
1211 b vector_irq + stubs_offset 1242 W(b) vector_dabt + stubs_offset
1212 b vector_fiq + stubs_offset 1243 W(b) vector_addrexcptn + stubs_offset
1244 W(b) vector_irq + stubs_offset
1245 W(b) vector_fiq + stubs_offset
1213 1246
1214 .globl __vectors_end 1247 .globl __vectors_end
1215__vectors_end: 1248__vectors_end:
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 8c3de1a350b5..807cfebb0f44 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -33,14 +33,7 @@ ret_fast_syscall:
33 /* perform architecture specific actions before user return */ 33 /* perform architecture specific actions before user return */
34 arch_ret_to_user r1, lr 34 arch_ret_to_user r1, lr
35 35
36 @ fast_restore_user_regs 36 restore_user_regs fast = 1, offset = S_OFF
37 ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
38 ldr lr, [sp, #S_OFF + S_PC]! @ get pc
39 msr spsr_cxsf, r1 @ save in spsr_svc
40 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
41 mov r0, r0
42 add sp, sp, #S_FRAME_SIZE - S_PC
43 movs pc, lr @ return & move spsr_svc into cpsr
44 UNWIND(.fnend ) 37 UNWIND(.fnend )
45 38
46/* 39/*
@@ -51,7 +44,7 @@ fast_work_pending:
51work_pending: 44work_pending:
52 tst r1, #_TIF_NEED_RESCHED 45 tst r1, #_TIF_NEED_RESCHED
53 bne work_resched 46 bne work_resched
54 tst r1, #_TIF_SIGPENDING 47 tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
55 beq no_work_pending 48 beq no_work_pending
56 mov r0, sp @ 'regs' 49 mov r0, sp @ 'regs'
57 mov r2, why @ 'syscall' 50 mov r2, why @ 'syscall'
@@ -73,14 +66,7 @@ no_work_pending:
73 /* perform architecture specific actions before user return */ 66 /* perform architecture specific actions before user return */
74 arch_ret_to_user r1, lr 67 arch_ret_to_user r1, lr
75 68
76 @ slow_restore_user_regs 69 restore_user_regs fast = 0, offset = 0
77 ldr r1, [sp, #S_PSR] @ get calling cpsr
78 ldr lr, [sp, #S_PC]! @ get pc
79 msr spsr_cxsf, r1 @ save in spsr_svc
80 ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
81 mov r0, r0
82 add sp, sp, #S_FRAME_SIZE - S_PC
83 movs pc, lr @ return & move spsr_svc into cpsr
84ENDPROC(ret_to_user) 70ENDPROC(ret_to_user)
85 71
86/* 72/*
@@ -132,6 +118,25 @@ ftrace_call:
132 118
133#else 119#else
134 120
121ENTRY(__gnu_mcount_nc)
122 stmdb sp!, {r0-r3, lr}
123 ldr r0, =ftrace_trace_function
124 ldr r2, [r0]
125 adr r0, ftrace_stub
126 cmp r0, r2
127 bne gnu_trace
128 ldmia sp!, {r0-r3, ip, lr}
129 bx ip
130
131gnu_trace:
132 ldr r1, [sp, #20] @ lr of instrumented routine
133 mov r0, lr
134 sub r0, r0, #MCOUNT_INSN_SIZE
135 mov lr, pc
136 mov pc, r2
137 ldmia sp!, {r0-r3, ip, lr}
138 bx ip
139
135ENTRY(mcount) 140ENTRY(mcount)
136 stmdb sp!, {r0-r3, lr} 141 stmdb sp!, {r0-r3, lr}
137 ldr r0, =ftrace_trace_function 142 ldr r0, =ftrace_trace_function
@@ -182,8 +187,10 @@ ftrace_stub:
182ENTRY(vector_swi) 187ENTRY(vector_swi)
183 sub sp, sp, #S_FRAME_SIZE 188 sub sp, sp, #S_FRAME_SIZE
184 stmia sp, {r0 - r12} @ Calling r0 - r12 189 stmia sp, {r0 - r12} @ Calling r0 - r12
185 add r8, sp, #S_PC 190 ARM( add r8, sp, #S_PC )
186 stmdb r8, {sp, lr}^ @ Calling sp, lr 191 ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
192 THUMB( mov r8, sp )
193 THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr
187 mrs r8, spsr @ called from non-FIQ mode, so ok. 194 mrs r8, spsr @ called from non-FIQ mode, so ok.
188 str lr, [sp, #S_PC] @ Save calling PC 195 str lr, [sp, #S_PC] @ Save calling PC
189 str r8, [sp, #S_PSR] @ Save CPSR 196 str r8, [sp, #S_PSR] @ Save CPSR
@@ -272,7 +279,7 @@ ENTRY(vector_swi)
272 bne __sys_trace 279 bne __sys_trace
273 280
274 cmp scno, #NR_syscalls @ check upper syscall limit 281 cmp scno, #NR_syscalls @ check upper syscall limit
275 adr lr, ret_fast_syscall @ return address 282 adr lr, BSYM(ret_fast_syscall) @ return address
276 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine 283 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
277 284
278 add r1, sp, #S_OFF 285 add r1, sp, #S_OFF
@@ -293,7 +300,7 @@ __sys_trace:
293 mov r0, #0 @ trace entry [IP = 0] 300 mov r0, #0 @ trace entry [IP = 0]
294 bl syscall_trace 301 bl syscall_trace
295 302
296 adr lr, __sys_trace_return @ return address 303 adr lr, BSYM(__sys_trace_return) @ return address
297 mov scno, r0 @ syscall number (possibly new) 304 mov scno, r0 @ syscall number (possibly new)
298 add r1, sp, #S_R0 + S_OFF @ pointer to regs 305 add r1, sp, #S_R0 + S_OFF @ pointer to regs
299 cmp scno, #NR_syscalls @ check upper syscall limit 306 cmp scno, #NR_syscalls @ check upper syscall limit
@@ -373,16 +380,6 @@ sys_clone_wrapper:
373 b sys_clone 380 b sys_clone
374ENDPROC(sys_clone_wrapper) 381ENDPROC(sys_clone_wrapper)
375 382
376sys_sigsuspend_wrapper:
377 add r3, sp, #S_OFF
378 b sys_sigsuspend
379ENDPROC(sys_sigsuspend_wrapper)
380
381sys_rt_sigsuspend_wrapper:
382 add r2, sp, #S_OFF
383 b sys_rt_sigsuspend
384ENDPROC(sys_rt_sigsuspend_wrapper)
385
386sys_sigreturn_wrapper: 383sys_sigreturn_wrapper:
387 add r0, sp, #S_OFF 384 add r0, sp, #S_OFF
388 b sys_sigreturn 385 b sys_sigreturn
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 87ab4e157997..a4eaf4f920c5 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -36,11 +36,6 @@
36#endif 36#endif
37 .endm 37 .endm
38 38
39 .macro get_thread_info, rd
40 mov \rd, sp, lsr #13
41 mov \rd, \rd, lsl #13
42 .endm
43
44 .macro alignment_trap, rtemp 39 .macro alignment_trap, rtemp
45#ifdef CONFIG_ALIGNMENT_TRAP 40#ifdef CONFIG_ALIGNMENT_TRAP
46 ldr \rtemp, .LCcralign 41 ldr \rtemp, .LCcralign
@@ -49,6 +44,93 @@
49#endif 44#endif
50 .endm 45 .endm
51 46
47 @
48 @ Store/load the USER SP and LR registers by switching to the SYS
49 @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not
50 @ available. Should only be called from SVC mode
51 @
52 .macro store_user_sp_lr, rd, rtemp, offset = 0
53 mrs \rtemp, cpsr
54 eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
55 msr cpsr_c, \rtemp @ switch to the SYS mode
56
57 str sp, [\rd, #\offset] @ save sp_usr
58 str lr, [\rd, #\offset + 4] @ save lr_usr
59
60 eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
61 msr cpsr_c, \rtemp @ switch back to the SVC mode
62 .endm
63
64 .macro load_user_sp_lr, rd, rtemp, offset = 0
65 mrs \rtemp, cpsr
66 eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
67 msr cpsr_c, \rtemp @ switch to the SYS mode
68
69 ldr sp, [\rd, #\offset] @ load sp_usr
70 ldr lr, [\rd, #\offset + 4] @ load lr_usr
71
72 eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
73 msr cpsr_c, \rtemp @ switch back to the SVC mode
74 .endm
75
76#ifndef CONFIG_THUMB2_KERNEL
77 .macro svc_exit, rpsr
78 msr spsr_cxsf, \rpsr
79 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
80 .endm
81
82 .macro restore_user_regs, fast = 0, offset = 0
83 ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
84 ldr lr, [sp, #\offset + S_PC]! @ get pc
85 msr spsr_cxsf, r1 @ save in spsr_svc
86 .if \fast
87 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
88 .else
89 ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
90 .endif
91 add sp, sp, #S_FRAME_SIZE - S_PC
92 movs pc, lr @ return & move spsr_svc into cpsr
93 .endm
94
95 .macro get_thread_info, rd
96 mov \rd, sp, lsr #13
97 mov \rd, \rd, lsl #13
98 .endm
99#else /* CONFIG_THUMB2_KERNEL */
100 .macro svc_exit, rpsr
101 ldr r0, [sp, #S_SP] @ top of the stack
102 ldr r1, [sp, #S_PC] @ return address
103 tst r0, #4 @ orig stack 8-byte aligned?
104 stmdb r0, {r1, \rpsr} @ rfe context
105 ldmia sp, {r0 - r12}
106 ldr lr, [sp, #S_LR]
107 addeq sp, sp, #S_FRAME_SIZE - 8 @ aligned
108 addne sp, sp, #S_FRAME_SIZE - 4 @ not aligned
109 rfeia sp!
110 .endm
111
112 .macro restore_user_regs, fast = 0, offset = 0
113 mov r2, sp
114 load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr
115 ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
116 ldr lr, [sp, #\offset + S_PC] @ get pc
117 add sp, sp, #\offset + S_SP
118 msr spsr_cxsf, r1 @ save in spsr_svc
119 .if \fast
120 ldmdb sp, {r1 - r12} @ get calling r1 - r12
121 .else
122 ldmdb sp, {r0 - r12} @ get calling r0 - r12
123 .endif
124 add sp, sp, #S_FRAME_SIZE - S_SP
125 movs pc, lr @ return & move spsr_svc into cpsr
126 .endm
127
128 .macro get_thread_info, rd
129 mov \rd, sp
130 lsr \rd, \rd, #13
131 mov \rd, \rd, lsl #13
132 .endm
133#endif /* !CONFIG_THUMB2_KERNEL */
52 134
53/* 135/*
54 * These are the registers used in the syscall handler, and allow us to 136 * These are the registers used in the syscall handler, and allow us to
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 991952c644d1..93ad576b2d74 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -14,6 +14,7 @@
14#define ATAG_CORE 0x54410001 14#define ATAG_CORE 0x54410001
15#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) 15#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
16 16
17 .align 2
17 .type __switch_data, %object 18 .type __switch_data, %object
18__switch_data: 19__switch_data:
19 .long __mmap_switched 20 .long __mmap_switched
@@ -51,7 +52,9 @@ __mmap_switched:
51 strcc fp, [r6],#4 52 strcc fp, [r6],#4
52 bcc 1b 53 bcc 1b
53 54
54 ldmia r3, {r4, r5, r6, r7, sp} 55 ARM( ldmia r3, {r4, r5, r6, r7, sp})
56 THUMB( ldmia r3, {r4, r5, r6, r7} )
57 THUMB( ldr sp, [r3, #16] )
55 str r9, [r4] @ Save processor ID 58 str r9, [r4] @ Save processor ID
56 str r1, [r5] @ Save machine type 59 str r1, [r5] @ Save machine type
57 str r2, [r6] @ Save atags pointer 60 str r2, [r6] @ Save atags pointer
@@ -155,7 +158,8 @@ ENDPROC(__error)
155 */ 158 */
156__lookup_processor_type: 159__lookup_processor_type:
157 adr r3, 3f 160 adr r3, 3f
158 ldmda r3, {r5 - r7} 161 ldmia r3, {r5 - r7}
162 add r3, r3, #8
159 sub r3, r3, r7 @ get offset between virt&phys 163 sub r3, r3, r7 @ get offset between virt&phys
160 add r5, r5, r3 @ convert virt addresses to 164 add r5, r5, r3 @ convert virt addresses to
161 add r6, r6, r3 @ physical address space 165 add r6, r6, r3 @ physical address space
@@ -185,9 +189,10 @@ ENDPROC(lookup_processor_type)
185 * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for 189 * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for
186 * more information about the __proc_info and __arch_info structures. 190 * more information about the __proc_info and __arch_info structures.
187 */ 191 */
188 .long __proc_info_begin 192 .align 2
1933: .long __proc_info_begin
189 .long __proc_info_end 194 .long __proc_info_end
1903: .long . 1954: .long .
191 .long __arch_info_begin 196 .long __arch_info_begin
192 .long __arch_info_end 197 .long __arch_info_end
193 198
@@ -203,7 +208,7 @@ ENDPROC(lookup_processor_type)
203 * r5 = mach_info pointer in physical address space 208 * r5 = mach_info pointer in physical address space
204 */ 209 */
205__lookup_machine_type: 210__lookup_machine_type:
206 adr r3, 3b 211 adr r3, 4b
207 ldmia r3, {r4, r5, r6} 212 ldmia r3, {r4, r5, r6}
208 sub r3, r3, r4 @ get offset between virt&phys 213 sub r3, r3, r4 @ get offset between virt&phys
209 add r5, r5, r3 @ convert virt addresses to 214 add r5, r5, r3 @ convert virt addresses to
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index cc87e1765ed2..e5dfc2895e24 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -34,7 +34,7 @@
34 */ 34 */
35 .section ".text.head", "ax" 35 .section ".text.head", "ax"
36ENTRY(stext) 36ENTRY(stext)
37 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode 37 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
38 @ and irqs disabled 38 @ and irqs disabled
39#ifndef CONFIG_CPU_CP15 39#ifndef CONFIG_CPU_CP15
40 ldr r9, =CONFIG_PROCESSOR_ID 40 ldr r9, =CONFIG_PROCESSOR_ID
@@ -50,8 +50,10 @@ ENTRY(stext)
50 50
51 ldr r13, __switch_data @ address to jump to after 51 ldr r13, __switch_data @ address to jump to after
52 @ the initialization is done 52 @ the initialization is done
53 adr lr, __after_proc_init @ return (PIC) address 53 adr lr, BSYM(__after_proc_init) @ return (PIC) address
54 add pc, r10, #PROCINFO_INITFUNC 54 ARM( add pc, r10, #PROCINFO_INITFUNC )
55 THUMB( add r12, r10, #PROCINFO_INITFUNC )
56 THUMB( mov pc, r12 )
55ENDPROC(stext) 57ENDPROC(stext)
56 58
57/* 59/*
@@ -59,7 +61,10 @@ ENDPROC(stext)
59 */ 61 */
60__after_proc_init: 62__after_proc_init:
61#ifdef CONFIG_CPU_CP15 63#ifdef CONFIG_CPU_CP15
62 mrc p15, 0, r0, c1, c0, 0 @ read control reg 64 /*
65 * CP15 system control register value returned in r0 from
66 * the CPU init function.
67 */
63#ifdef CONFIG_ALIGNMENT_TRAP 68#ifdef CONFIG_ALIGNMENT_TRAP
64 orr r0, r0, #CR_A 69 orr r0, r0, #CR_A
65#else 70#else
@@ -82,7 +87,8 @@ __after_proc_init:
82 mcr p15, 0, r0, c1, c0, 0 @ write control reg 87 mcr p15, 0, r0, c1, c0, 0 @ write control reg
83#endif /* CONFIG_CPU_CP15 */ 88#endif /* CONFIG_CPU_CP15 */
84 89
85 mov pc, r13 @ clear the BSS and jump 90 mov r3, r13
91 mov pc, r3 @ clear the BSS and jump
86 @ to start_kernel 92 @ to start_kernel
87ENDPROC(__after_proc_init) 93ENDPROC(__after_proc_init)
88 .ltorg 94 .ltorg
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 21e17dc94cb5..38ccbe1d3b2c 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -76,7 +76,7 @@
76 */ 76 */
77 .section ".text.head", "ax" 77 .section ".text.head", "ax"
78ENTRY(stext) 78ENTRY(stext)
79 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode 79 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
80 @ and irqs disabled 80 @ and irqs disabled
81 mrc p15, 0, r9, c0, c0 @ get processor id 81 mrc p15, 0, r9, c0, c0 @ get processor id
82 bl __lookup_processor_type @ r5=procinfo r9=cpuid 82 bl __lookup_processor_type @ r5=procinfo r9=cpuid
@@ -97,8 +97,10 @@ ENTRY(stext)
97 */ 97 */
98 ldr r13, __switch_data @ address to jump to after 98 ldr r13, __switch_data @ address to jump to after
99 @ mmu has been enabled 99 @ mmu has been enabled
100 adr lr, __enable_mmu @ return (PIC) address 100 adr lr, BSYM(__enable_mmu) @ return (PIC) address
101 add pc, r10, #PROCINFO_INITFUNC 101 ARM( add pc, r10, #PROCINFO_INITFUNC )
102 THUMB( add r12, r10, #PROCINFO_INITFUNC )
103 THUMB( mov pc, r12 )
102ENDPROC(stext) 104ENDPROC(stext)
103 105
104#if defined(CONFIG_SMP) 106#if defined(CONFIG_SMP)
@@ -110,7 +112,7 @@ ENTRY(secondary_startup)
110 * the processor type - there is no need to check the machine type 112 * the processor type - there is no need to check the machine type
111 * as it has already been validated by the primary processor. 113 * as it has already been validated by the primary processor.
112 */ 114 */
113 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE 115 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
114 mrc p15, 0, r9, c0, c0 @ get processor id 116 mrc p15, 0, r9, c0, c0 @ get processor id
115 bl __lookup_processor_type 117 bl __lookup_processor_type
116 movs r10, r5 @ invalid processor? 118 movs r10, r5 @ invalid processor?
@@ -121,12 +123,15 @@ ENTRY(secondary_startup)
121 * Use the page tables supplied from __cpu_up. 123 * Use the page tables supplied from __cpu_up.
122 */ 124 */
123 adr r4, __secondary_data 125 adr r4, __secondary_data
124 ldmia r4, {r5, r7, r13} @ address to jump to after 126 ldmia r4, {r5, r7, r12} @ address to jump to after
125 sub r4, r4, r5 @ mmu has been enabled 127 sub r4, r4, r5 @ mmu has been enabled
126 ldr r4, [r7, r4] @ get secondary_data.pgdir 128 ldr r4, [r7, r4] @ get secondary_data.pgdir
127 adr lr, __enable_mmu @ return address 129 adr lr, BSYM(__enable_mmu) @ return address
128 add pc, r10, #PROCINFO_INITFUNC @ initialise processor 130 mov r13, r12 @ __secondary_switched address
129 @ (return control reg) 131 ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor
132 @ (return control reg)
133 THUMB( add r12, r10, #PROCINFO_INITFUNC )
134 THUMB( mov pc, r12 )
130ENDPROC(secondary_startup) 135ENDPROC(secondary_startup)
131 136
132 /* 137 /*
@@ -193,8 +198,8 @@ __turn_mmu_on:
193 mcr p15, 0, r0, c1, c0, 0 @ write control reg 198 mcr p15, 0, r0, c1, c0, 0 @ write control reg
194 mrc p15, 0, r3, c0, c0, 0 @ read id reg 199 mrc p15, 0, r3, c0, c0, 0 @ read id reg
195 mov r3, r3 200 mov r3, r3
196 mov r3, r3 201 mov r3, r13
197 mov pc, r13 202 mov pc, r3
198ENDPROC(__turn_mmu_on) 203ENDPROC(__turn_mmu_on)
199 204
200 205
@@ -235,7 +240,8 @@ __create_page_tables:
235 * will be removed by paging_init(). We use our current program 240 * will be removed by paging_init(). We use our current program
236 * counter to determine corresponding section base address. 241 * counter to determine corresponding section base address.
237 */ 242 */
238 mov r6, pc, lsr #20 @ start of kernel section 243 mov r6, pc
244 mov r6, r6, lsr #20 @ start of kernel section
239 orr r3, r7, r6, lsl #20 @ flags + kernel base 245 orr r3, r7, r6, lsl #20 @ flags + kernel base
240 str r3, [r4, r6, lsl #2] @ identity mapping 246 str r3, [r4, r6, lsl #2] @ identity mapping
241 247
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b7c3490eaa24..c9a8619f3856 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -86,7 +86,7 @@ int show_interrupts(struct seq_file *p, void *v)
86unlock: 86unlock:
87 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 87 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
88 } else if (i == NR_IRQS) { 88 } else if (i == NR_IRQS) {
89#ifdef CONFIG_ARCH_ACORN 89#ifdef CONFIG_FIQ
90 show_fiq_list(p, v); 90 show_fiq_list(p, v);
91#endif 91#endif
92#ifdef CONFIG_SMP 92#ifdef CONFIG_SMP
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index bac03c81489d..f28c5e9c51ea 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -102,6 +102,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
102 unsigned long loc; 102 unsigned long loc;
103 Elf32_Sym *sym; 103 Elf32_Sym *sym;
104 s32 offset; 104 s32 offset;
105 u32 upper, lower, sign, j1, j2;
105 106
106 offset = ELF32_R_SYM(rel->r_info); 107 offset = ELF32_R_SYM(rel->r_info);
107 if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { 108 if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
@@ -184,6 +185,58 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
184 (offset & 0x0fff); 185 (offset & 0x0fff);
185 break; 186 break;
186 187
188 case R_ARM_THM_CALL:
189 case R_ARM_THM_JUMP24:
190 upper = *(u16 *)loc;
191 lower = *(u16 *)(loc + 2);
192
193 /*
194 * 25 bit signed address range (Thumb-2 BL and B.W
195 * instructions):
196 * S:I1:I2:imm10:imm11:0
197 * where:
198 * S = upper[10] = offset[24]
199 * I1 = ~(J1 ^ S) = offset[23]
200 * I2 = ~(J2 ^ S) = offset[22]
201 * imm10 = upper[9:0] = offset[21:12]
202 * imm11 = lower[10:0] = offset[11:1]
203 * J1 = lower[13]
204 * J2 = lower[11]
205 */
206 sign = (upper >> 10) & 1;
207 j1 = (lower >> 13) & 1;
208 j2 = (lower >> 11) & 1;
209 offset = (sign << 24) | ((~(j1 ^ sign) & 1) << 23) |
210 ((~(j2 ^ sign) & 1) << 22) |
211 ((upper & 0x03ff) << 12) |
212 ((lower & 0x07ff) << 1);
213 if (offset & 0x01000000)
214 offset -= 0x02000000;
215 offset += sym->st_value - loc;
216
217 /* only Thumb addresses allowed (no interworking) */
218 if (!(offset & 1) ||
219 offset <= (s32)0xff000000 ||
220 offset >= (s32)0x01000000) {
221 printk(KERN_ERR
222 "%s: relocation out of range, section "
223 "%d reloc %d sym '%s'\n", module->name,
224 relindex, i, strtab + sym->st_name);
225 return -ENOEXEC;
226 }
227
228 sign = (offset >> 24) & 1;
229 j1 = sign ^ (~(offset >> 23) & 1);
230 j2 = sign ^ (~(offset >> 22) & 1);
231 *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) |
232 ((offset >> 12) & 0x03ff));
233 *(u16 *)(loc + 2) = (u16)((lower & 0xd000) |
234 (j1 << 13) | (j2 << 11) |
235 ((offset >> 1) & 0x07ff));
236 upper = *(u16 *)loc;
237 lower = *(u16 *)(loc + 2);
238 break;
239
187 default: 240 default:
188 printk(KERN_ERR "%s: unknown relocation: %u\n", 241 printk(KERN_ERR "%s: unknown relocation: %u\n",
189 module->name, ELF32_R_TYPE(rel->r_info)); 242 module->name, ELF32_R_TYPE(rel->r_info));
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 39196dff478c..790fbee92ec5 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -388,7 +388,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
388 regs.ARM_r2 = (unsigned long)fn; 388 regs.ARM_r2 = (unsigned long)fn;
389 regs.ARM_r3 = (unsigned long)kernel_thread_exit; 389 regs.ARM_r3 = (unsigned long)kernel_thread_exit;
390 regs.ARM_pc = (unsigned long)kernel_thread_helper; 390 regs.ARM_pc = (unsigned long)kernel_thread_helper;
391 regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE; 391 regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
392 392
393 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 393 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
394} 394}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 89882a1d0187..a2ea3854cb3c 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -521,7 +521,13 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
521 return -EIO; 521 return -EIO;
522 522
523 tmp = 0; 523 tmp = 0;
524 if (off < sizeof(struct pt_regs)) 524 if (off == PT_TEXT_ADDR)
525 tmp = tsk->mm->start_code;
526 else if (off == PT_DATA_ADDR)
527 tmp = tsk->mm->start_data;
528 else if (off == PT_TEXT_END_ADDR)
529 tmp = tsk->mm->end_code;
530 else if (off < sizeof(struct pt_regs))
525 tmp = get_user_reg(tsk, off >> 2); 531 tmp = get_user_reg(tsk, off >> 2);
526 532
527 return put_user(tmp, ret); 533 return put_user(tmp, ret);
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
new file mode 100644
index 000000000000..df246da4ceca
--- /dev/null
+++ b/arch/arm/kernel/return_address.c
@@ -0,0 +1,71 @@
1/*
2 * arch/arm/kernel/return_address.c
3 *
4 * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
5 * for Pengutronix
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/module.h>
12
13#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
14#include <linux/sched.h>
15
16#include <asm/stacktrace.h>
17
18struct return_address_data {
19 unsigned int level;
20 void *addr;
21};
22
23static int save_return_addr(struct stackframe *frame, void *d)
24{
25 struct return_address_data *data = d;
26
27 if (!data->level) {
28 data->addr = (void *)frame->lr;
29
30 return 1;
31 } else {
32 --data->level;
33 return 0;
34 }
35}
36
37void *return_address(unsigned int level)
38{
39 struct return_address_data data;
40 struct stackframe frame;
41 register unsigned long current_sp asm ("sp");
42
43 data.level = level + 1;
44
45 frame.fp = (unsigned long)__builtin_frame_address(0);
46 frame.sp = current_sp;
47 frame.lr = (unsigned long)__builtin_return_address(0);
48 frame.pc = (unsigned long)return_address;
49
50 walk_stackframe(&frame, save_return_addr, &data);
51
52 if (!data.level)
53 return data.addr;
54 else
55 return NULL;
56}
57
58#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
59
60#if defined(CONFIG_ARM_UNWIND)
61#warning "TODO: return_address should use unwind tables"
62#endif
63
64void *return_address(unsigned int level)
65{
66 return NULL;
67}
68
69#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
70
71EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index bc5e4128f9f3..d4d4f77c91b2 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -25,6 +25,7 @@
25#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27 27
28#include <asm/unified.h>
28#include <asm/cpu.h> 29#include <asm/cpu.h>
29#include <asm/cputype.h> 30#include <asm/cputype.h>
30#include <asm/elf.h> 31#include <asm/elf.h>
@@ -327,25 +328,38 @@ void cpu_init(void)
327 } 328 }
328 329
329 /* 330 /*
331 * Define the placement constraint for the inline asm directive below.
332 * In Thumb-2, msr with an immediate value is not allowed.
333 */
334#ifdef CONFIG_THUMB2_KERNEL
335#define PLC "r"
336#else
337#define PLC "I"
338#endif
339
340 /*
330 * setup stacks for re-entrant exception handlers 341 * setup stacks for re-entrant exception handlers
331 */ 342 */
332 __asm__ ( 343 __asm__ (
333 "msr cpsr_c, %1\n\t" 344 "msr cpsr_c, %1\n\t"
334 "add sp, %0, %2\n\t" 345 "add r14, %0, %2\n\t"
346 "mov sp, r14\n\t"
335 "msr cpsr_c, %3\n\t" 347 "msr cpsr_c, %3\n\t"
336 "add sp, %0, %4\n\t" 348 "add r14, %0, %4\n\t"
349 "mov sp, r14\n\t"
337 "msr cpsr_c, %5\n\t" 350 "msr cpsr_c, %5\n\t"
338 "add sp, %0, %6\n\t" 351 "add r14, %0, %6\n\t"
352 "mov sp, r14\n\t"
339 "msr cpsr_c, %7" 353 "msr cpsr_c, %7"
340 : 354 :
341 : "r" (stk), 355 : "r" (stk),
342 "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), 356 PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
343 "I" (offsetof(struct stack, irq[0])), 357 "I" (offsetof(struct stack, irq[0])),
344 "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE), 358 PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
345 "I" (offsetof(struct stack, abt[0])), 359 "I" (offsetof(struct stack, abt[0])),
346 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), 360 PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
347 "I" (offsetof(struct stack, und[0])), 361 "I" (offsetof(struct stack, und[0])),
348 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE) 362 PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
349 : "r14"); 363 : "r14");
350} 364}
351 365
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index f6bc5d442782..1423a3419789 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -12,6 +12,7 @@
12#include <linux/personality.h> 12#include <linux/personality.h>
13#include <linux/freezer.h> 13#include <linux/freezer.h>
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <linux/tracehook.h>
15 16
16#include <asm/elf.h> 17#include <asm/elf.h>
17#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
@@ -47,57 +48,22 @@ const unsigned long sigreturn_codes[7] = {
47 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, 48 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
48}; 49};
49 50
50static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
51
52/* 51/*
53 * atomically swap in the new signal mask, and wait for a signal. 52 * atomically swap in the new signal mask, and wait for a signal.
54 */ 53 */
55asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) 54asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
56{ 55{
57 sigset_t saveset;
58
59 mask &= _BLOCKABLE; 56 mask &= _BLOCKABLE;
60 spin_lock_irq(&current->sighand->siglock); 57 spin_lock_irq(&current->sighand->siglock);
61 saveset = current->blocked; 58 current->saved_sigmask = current->blocked;
62 siginitset(&current->blocked, mask); 59 siginitset(&current->blocked, mask);
63 recalc_sigpending(); 60 recalc_sigpending();
64 spin_unlock_irq(&current->sighand->siglock); 61 spin_unlock_irq(&current->sighand->siglock);
65 regs->ARM_r0 = -EINTR;
66 62
67 while (1) { 63 current->state = TASK_INTERRUPTIBLE;
68 current->state = TASK_INTERRUPTIBLE; 64 schedule();
69 schedule(); 65 set_restore_sigmask();
70 if (do_signal(&saveset, regs, 0)) 66 return -ERESTARTNOHAND;
71 return regs->ARM_r0;
72 }
73}
74
75asmlinkage int
76sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
77{
78 sigset_t saveset, newset;
79
80 /* XXX: Don't preclude handling different sized sigset_t's. */
81 if (sigsetsize != sizeof(sigset_t))
82 return -EINVAL;
83
84 if (copy_from_user(&newset, unewset, sizeof(newset)))
85 return -EFAULT;
86 sigdelsetmask(&newset, ~_BLOCKABLE);
87
88 spin_lock_irq(&current->sighand->siglock);
89 saveset = current->blocked;
90 current->blocked = newset;
91 recalc_sigpending();
92 spin_unlock_irq(&current->sighand->siglock);
93 regs->ARM_r0 = -EINTR;
94
95 while (1) {
96 current->state = TASK_INTERRUPTIBLE;
97 schedule();
98 if (do_signal(&saveset, regs, 0))
99 return regs->ARM_r0;
100 }
101} 67}
102 68
103asmlinkage int 69asmlinkage int
@@ -545,7 +511,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
545/* 511/*
546 * OK, we're invoking a handler 512 * OK, we're invoking a handler
547 */ 513 */
548static void 514static int
549handle_signal(unsigned long sig, struct k_sigaction *ka, 515handle_signal(unsigned long sig, struct k_sigaction *ka,
550 siginfo_t *info, sigset_t *oldset, 516 siginfo_t *info, sigset_t *oldset,
551 struct pt_regs * regs, int syscall) 517 struct pt_regs * regs, int syscall)
@@ -596,7 +562,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
596 562
597 if (ret != 0) { 563 if (ret != 0) {
598 force_sigsegv(sig, tsk); 564 force_sigsegv(sig, tsk);
599 return; 565 return ret;
600 } 566 }
601 567
602 /* 568 /*
@@ -610,6 +576,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
610 recalc_sigpending(); 576 recalc_sigpending();
611 spin_unlock_irq(&tsk->sighand->siglock); 577 spin_unlock_irq(&tsk->sighand->siglock);
612 578
579 return 0;
613} 580}
614 581
615/* 582/*
@@ -621,7 +588,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
621 * the kernel can handle, and then we build all the user-level signal handling 588 * the kernel can handle, and then we build all the user-level signal handling
622 * stack-frames in one go after that. 589 * stack-frames in one go after that.
623 */ 590 */
624static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) 591static void do_signal(struct pt_regs *regs, int syscall)
625{ 592{
626 struct k_sigaction ka; 593 struct k_sigaction ka;
627 siginfo_t info; 594 siginfo_t info;
@@ -634,7 +601,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
634 * if so. 601 * if so.
635 */ 602 */
636 if (!user_mode(regs)) 603 if (!user_mode(regs))
637 return 0; 604 return;
638 605
639 if (try_to_freeze()) 606 if (try_to_freeze())
640 goto no_signal; 607 goto no_signal;
@@ -643,9 +610,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
643 610
644 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 611 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
645 if (signr > 0) { 612 if (signr > 0) {
646 handle_signal(signr, &ka, &info, oldset, regs, syscall); 613 sigset_t *oldset;
614
615 if (test_thread_flag(TIF_RESTORE_SIGMASK))
616 oldset = &current->saved_sigmask;
617 else
618 oldset = &current->blocked;
619 if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
620 /*
621 * A signal was successfully delivered; the saved
622 * sigmask will have been stored in the signal frame,
623 * and will be restored by sigreturn, so we can simply
624 * clear the TIF_RESTORE_SIGMASK flag.
625 */
626 if (test_thread_flag(TIF_RESTORE_SIGMASK))
627 clear_thread_flag(TIF_RESTORE_SIGMASK);
628 }
647 single_step_set(current); 629 single_step_set(current);
648 return 1; 630 return;
649 } 631 }
650 632
651 no_signal: 633 no_signal:
@@ -697,14 +679,28 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
697 regs->ARM_r0 == -ERESTARTNOINTR) { 679 regs->ARM_r0 == -ERESTARTNOINTR) {
698 setup_syscall_restart(regs); 680 setup_syscall_restart(regs);
699 } 681 }
682
683 /* If there's no signal to deliver, we just put the saved sigmask
684 * back.
685 */
686 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
687 clear_thread_flag(TIF_RESTORE_SIGMASK);
688 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
689 }
700 } 690 }
701 single_step_set(current); 691 single_step_set(current);
702 return 0;
703} 692}
704 693
705asmlinkage void 694asmlinkage void
706do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) 695do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
707{ 696{
708 if (thread_flags & _TIF_SIGPENDING) 697 if (thread_flags & _TIF_SIGPENDING)
709 do_signal(&current->blocked, regs, syscall); 698 do_signal(regs, syscall);
699
700 if (thread_flags & _TIF_NOTIFY_RESUME) {
701 clear_thread_flag(TIF_NOTIFY_RESUME);
702 tracehook_notify_resume(regs);
703 if (current->replacement_session_keyring)
704 key_replace_session_keyring();
705 }
710} 706}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 9f444e5cc165..20b7411e47fd 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -21,7 +21,7 @@
21 * Note that with framepointer enabled, even the leaf functions have the same 21 * Note that with framepointer enabled, even the leaf functions have the same
22 * prologue and epilogue, therefore we can ignore the LR value in this case. 22 * prologue and epilogue, therefore we can ignore the LR value in this case.
23 */ 23 */
24int unwind_frame(struct stackframe *frame) 24int notrace unwind_frame(struct stackframe *frame)
25{ 25{
26 unsigned long high, low; 26 unsigned long high, low;
27 unsigned long fp = frame->fp; 27 unsigned long fp = frame->fp;
@@ -43,7 +43,7 @@ int unwind_frame(struct stackframe *frame)
43} 43}
44#endif 44#endif
45 45
46void walk_stackframe(struct stackframe *frame, 46void notrace walk_stackframe(struct stackframe *frame,
47 int (*fn)(struct stackframe *, void *), void *data) 47 int (*fn)(struct stackframe *, void *), void *data)
48{ 48{
49 while (1) { 49 while (1) {
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index dd56e11f339a..39baf1128bfa 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -62,7 +62,11 @@ struct unwind_ctrl_block {
62}; 62};
63 63
64enum regs { 64enum regs {
65#ifdef CONFIG_THUMB2_KERNEL
66 FP = 7,
67#else
65 FP = 11, 68 FP = 11,
69#endif
66 SP = 13, 70 SP = 13,
67 LR = 14, 71 LR = 14,
68 PC = 15 72 PC = 15
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
index 1154d924080b..638deb13da1c 100644
--- a/arch/arm/lib/ashldi3.S
+++ b/arch/arm/lib/ashldi3.S
@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsl)
43 rsb ip, r2, #32 43 rsb ip, r2, #32
44 movmi ah, ah, lsl r2 44 movmi ah, ah, lsl r2
45 movpl ah, al, lsl r3 45 movpl ah, al, lsl r3
46 orrmi ah, ah, al, lsr ip 46 ARM( orrmi ah, ah, al, lsr ip )
47 THUMB( lsrmi r3, al, ip )
48 THUMB( orrmi ah, ah, r3 )
47 mov al, al, lsl r2 49 mov al, al, lsl r2
48 mov pc, lr 50 mov pc, lr
49 51
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
index 9f8b35572f8c..015e8aa5a1d1 100644
--- a/arch/arm/lib/ashrdi3.S
+++ b/arch/arm/lib/ashrdi3.S
@@ -43,7 +43,9 @@ ENTRY(__aeabi_lasr)
43 rsb ip, r2, #32 43 rsb ip, r2, #32
44 movmi al, al, lsr r2 44 movmi al, al, lsr r2
45 movpl al, ah, asr r3 45 movpl al, ah, asr r3
46 orrmi al, al, ah, lsl ip 46 ARM( orrmi al, al, ah, lsl ip )
47 THUMB( lslmi r3, ah, ip )
48 THUMB( orrmi al, al, r3 )
47 mov ah, ah, asr r2 49 mov ah, ah, asr r2
48 mov pc, lr 50 mov pc, lr
49 51
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index b0951d0e8b2c..aaf7220d9e30 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -38,7 +38,9 @@ ENDPROC(c_backtrace)
38 beq no_frame @ we have no stack frames 38 beq no_frame @ we have no stack frames
39 39
40 tst r1, #0x10 @ 26 or 32-bit mode? 40 tst r1, #0x10 @ 26 or 32-bit mode?
41 moveq mask, #0xfc000003 @ mask for 26-bit 41 ARM( moveq mask, #0xfc000003 )
42 THUMB( moveq mask, #0xfc000000 )
43 THUMB( orreq mask, #0x03 )
42 movne mask, #0 @ mask for 32-bit 44 movne mask, #0 @ mask for 32-bit
43 45
441: stmfd sp!, {pc} @ calculate offset of PC stored 461: stmfd sp!, {pc} @ calculate offset of PC stored
@@ -126,7 +128,9 @@ ENDPROC(c_backtrace)
126 mov reg, #10 128 mov reg, #10
127 mov r7, #0 129 mov r7, #0
1281: mov r3, #1 1301: mov r3, #1
129 tst instr, r3, lsl reg 131 ARM( tst instr, r3, lsl reg )
132 THUMB( lsl r3, reg )
133 THUMB( tst instr, r3 )
130 beq 2f 134 beq 2f
131 add r7, r7, #1 135 add r7, r7, #1
132 teq r7, #6 136 teq r7, #6
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index c7f2627385e7..d42252918bfb 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -60,8 +60,8 @@
60 tst r2, r0, lsl r3 60 tst r2, r0, lsl r3
61 \instr r2, r2, r0, lsl r3 61 \instr r2, r2, r0, lsl r3
62 \store r2, [r1] 62 \store r2, [r1]
63 restore_irqs ip
64 moveq r0, #0 63 moveq r0, #0
64 restore_irqs ip
65 mov pc, lr 65 mov pc, lr
66 .endm 66 .endm
67#endif 67#endif
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 844f56785ebc..1279abd8b886 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -27,21 +27,20 @@ WEAK(__clear_user)
27 ands ip, r0, #3 27 ands ip, r0, #3
28 beq 1f 28 beq 1f
29 cmp ip, #2 29 cmp ip, #2
30USER( strbt r2, [r0], #1) 30 strusr r2, r0, 1
31USER( strlebt r2, [r0], #1) 31 strusr r2, r0, 1, le
32USER( strltbt r2, [r0], #1) 32 strusr r2, r0, 1, lt
33 rsb ip, ip, #4 33 rsb ip, ip, #4
34 sub r1, r1, ip @ 7 6 5 4 3 2 1 34 sub r1, r1, ip @ 7 6 5 4 3 2 1
351: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 351: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
36USER( strplt r2, [r0], #4) 36 strusr r2, r0, 4, pl, rept=2
37USER( strplt r2, [r0], #4)
38 bpl 1b 37 bpl 1b
39 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 38 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
40USER( strplt r2, [r0], #4) 39 strusr r2, r0, 4, pl
412: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x 402: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
42USER( strnebt r2, [r0], #1) 41 strusr r2, r0, 1, ne, rept=2
43USER( strnebt r2, [r0], #1)
44 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 42 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
43 it ne @ explicit IT needed for the label
45USER( strnebt r2, [r0]) 44USER( strnebt r2, [r0])
46 mov r0, #0 45 mov r0, #0
47 ldmfd sp!, {r1, pc} 46 ldmfd sp!, {r1, pc}
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 56799a165cc4..e4fe124acedc 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -33,11 +33,15 @@
33 * Number of bytes NOT copied. 33 * Number of bytes NOT copied.
34 */ 34 */
35 35
36#ifndef CONFIG_THUMB2_KERNEL
37#define LDR1W_SHIFT 0
38#else
39#define LDR1W_SHIFT 1
40#endif
41#define STR1W_SHIFT 0
42
36 .macro ldr1w ptr reg abort 43 .macro ldr1w ptr reg abort
37100: ldrt \reg, [\ptr], #4 44 ldrusr \reg, \ptr, 4, abort=\abort
38 .section __ex_table, "a"
39 .long 100b, \abort
40 .previous
41 .endm 45 .endm
42 46
43 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort 47 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
@@ -53,14 +57,11 @@
53 .endm 57 .endm
54 58
55 .macro ldr1b ptr reg cond=al abort 59 .macro ldr1b ptr reg cond=al abort
56100: ldr\cond\()bt \reg, [\ptr], #1 60 ldrusr \reg, \ptr, 1, \cond, abort=\abort
57 .section __ex_table, "a"
58 .long 100b, \abort
59 .previous
60 .endm 61 .endm
61 62
62 .macro str1w ptr reg abort 63 .macro str1w ptr reg abort
63 str \reg, [\ptr], #4 64 W(str) \reg, [\ptr], #4
64 .endm 65 .endm
65 66
66 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 67 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 139cce646055..805e3f8fb007 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -57,6 +57,13 @@
57 * 57 *
58 * Restore registers with the values previously saved with the 58 * Restore registers with the values previously saved with the
59 * 'preserv' macro. Called upon code termination. 59 * 'preserv' macro. Called upon code termination.
60 *
61 * LDR1W_SHIFT
62 * STR1W_SHIFT
63 *
64 * Correction to be applied to the "ip" register when branching into
65 * the ldr1w or str1w instructions (some of these macros may expand to
66 * than one 32bit instruction in Thumb-2)
60 */ 67 */
61 68
62 69
@@ -99,9 +106,15 @@
99 106
1005: ands ip, r2, #28 1075: ands ip, r2, #28
101 rsb ip, ip, #32 108 rsb ip, ip, #32
109#if LDR1W_SHIFT > 0
110 lsl ip, ip, #LDR1W_SHIFT
111#endif
102 addne pc, pc, ip @ C is always clear here 112 addne pc, pc, ip @ C is always clear here
103 b 7f 113 b 7f
1046: nop 1146:
115 .rept (1 << LDR1W_SHIFT)
116 W(nop)
117 .endr
105 ldr1w r1, r3, abort=20f 118 ldr1w r1, r3, abort=20f
106 ldr1w r1, r4, abort=20f 119 ldr1w r1, r4, abort=20f
107 ldr1w r1, r5, abort=20f 120 ldr1w r1, r5, abort=20f
@@ -110,9 +123,16 @@
110 ldr1w r1, r8, abort=20f 123 ldr1w r1, r8, abort=20f
111 ldr1w r1, lr, abort=20f 124 ldr1w r1, lr, abort=20f
112 125
126#if LDR1W_SHIFT < STR1W_SHIFT
127 lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
128#elif LDR1W_SHIFT > STR1W_SHIFT
129 lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
130#endif
113 add pc, pc, ip 131 add pc, pc, ip
114 nop 132 nop
115 nop 133 .rept (1 << STR1W_SHIFT)
134 W(nop)
135 .endr
116 str1w r0, r3, abort=20f 136 str1w r0, r3, abort=20f
117 str1w r0, r4, abort=20f 137 str1w r0, r4, abort=20f
118 str1w r0, r5, abort=20f 138 str1w r0, r5, abort=20f
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 878820f0a320..1a71e1584442 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -33,8 +33,15 @@
33 * Number of bytes NOT copied. 33 * Number of bytes NOT copied.
34 */ 34 */
35 35
36#define LDR1W_SHIFT 0
37#ifndef CONFIG_THUMB2_KERNEL
38#define STR1W_SHIFT 0
39#else
40#define STR1W_SHIFT 1
41#endif
42
36 .macro ldr1w ptr reg abort 43 .macro ldr1w ptr reg abort
37 ldr \reg, [\ptr], #4 44 W(ldr) \reg, [\ptr], #4
38 .endm 45 .endm
39 46
40 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort 47 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
@@ -50,10 +57,7 @@
50 .endm 57 .endm
51 58
52 .macro str1w ptr reg abort 59 .macro str1w ptr reg abort
53100: strt \reg, [\ptr], #4 60 strusr \reg, \ptr, 4, abort=\abort
54 .section __ex_table, "a"
55 .long 100b, \abort
56 .previous
57 .endm 61 .endm
58 62
59 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 63 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
@@ -68,10 +72,7 @@
68 .endm 72 .endm
69 73
70 .macro str1b ptr reg cond=al abort 74 .macro str1b ptr reg cond=al abort
71100: str\cond\()bt \reg, [\ptr], #1 75 strusr \reg, \ptr, 1, \cond, abort=\abort
72 .section __ex_table, "a"
73 .long 100b, \abort
74 .previous
75 .endm 76 .endm
76 77
77 .macro enter reg1 reg2 78 .macro enter reg1 reg2
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 14677fb4b0c4..fd0e9dcd9fdc 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -26,50 +26,28 @@
26 .endm 26 .endm
27 27
28 .macro load1b, reg1 28 .macro load1b, reg1
299999: ldrbt \reg1, [r0], $1 29 ldrusr \reg1, r0, 1
30 .section __ex_table, "a"
31 .align 3
32 .long 9999b, 6001f
33 .previous
34 .endm 30 .endm
35 31
36 .macro load2b, reg1, reg2 32 .macro load2b, reg1, reg2
379999: ldrbt \reg1, [r0], $1 33 ldrusr \reg1, r0, 1
389998: ldrbt \reg2, [r0], $1 34 ldrusr \reg2, r0, 1
39 .section __ex_table, "a"
40 .long 9999b, 6001f
41 .long 9998b, 6001f
42 .previous
43 .endm 35 .endm
44 36
45 .macro load1l, reg1 37 .macro load1l, reg1
469999: ldrt \reg1, [r0], $4 38 ldrusr \reg1, r0, 4
47 .section __ex_table, "a"
48 .align 3
49 .long 9999b, 6001f
50 .previous
51 .endm 39 .endm
52 40
53 .macro load2l, reg1, reg2 41 .macro load2l, reg1, reg2
549999: ldrt \reg1, [r0], $4 42 ldrusr \reg1, r0, 4
559998: ldrt \reg2, [r0], $4 43 ldrusr \reg2, r0, 4
56 .section __ex_table, "a"
57 .long 9999b, 6001f
58 .long 9998b, 6001f
59 .previous
60 .endm 44 .endm
61 45
62 .macro load4l, reg1, reg2, reg3, reg4 46 .macro load4l, reg1, reg2, reg3, reg4
639999: ldrt \reg1, [r0], $4 47 ldrusr \reg1, r0, 4
649998: ldrt \reg2, [r0], $4 48 ldrusr \reg2, r0, 4
659997: ldrt \reg3, [r0], $4 49 ldrusr \reg3, r0, 4
669996: ldrt \reg4, [r0], $4 50 ldrusr \reg4, r0, 4
67 .section __ex_table, "a"
68 .long 9999b, 6001f
69 .long 9998b, 6001f
70 .long 9997b, 6001f
71 .long 9996b, 6001f
72 .previous
73 .endm 51 .endm
74 52
75/* 53/*
@@ -92,14 +70,14 @@
92 */ 70 */
93 .section .fixup,"ax" 71 .section .fixup,"ax"
94 .align 4 72 .align 4
956001: mov r4, #-EFAULT 739001: mov r4, #-EFAULT
96 ldr r5, [fp, #4] @ *err_ptr 74 ldr r5, [fp, #4] @ *err_ptr
97 str r4, [r5] 75 str r4, [r5]
98 ldmia sp, {r1, r2} @ retrieve dst, len 76 ldmia sp, {r1, r2} @ retrieve dst, len
99 add r2, r2, r1 77 add r2, r2, r1
100 mov r0, #0 @ zero the buffer 78 mov r0, #0 @ zero the buffer
1016002: teq r2, r1 799002: teq r2, r1
102 strneb r0, [r1], #1 80 strneb r0, [r1], #1
103 bne 6002b 81 bne 9002b
104 load_regs 82 load_regs
105 .previous 83 .previous
diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S
index 1425e789ba86..faa7748142da 100644
--- a/arch/arm/lib/div64.S
+++ b/arch/arm/lib/div64.S
@@ -177,7 +177,9 @@ ENTRY(__do_div64)
177 mov yh, xh, lsr ip 177 mov yh, xh, lsr ip
178 mov yl, xl, lsr ip 178 mov yl, xl, lsr ip
179 rsb ip, ip, #32 179 rsb ip, ip, #32
180 orr yl, yl, xh, lsl ip 180 ARM( orr yl, yl, xh, lsl ip )
181 THUMB( lsl xh, xh, ip )
182 THUMB( orr yl, yl, xh )
181 mov xh, xl, lsl ip 183 mov xh, xl, lsl ip
182 mov xh, xh, lsr ip 184 mov xh, xh, lsr ip
183 mov pc, lr 185 mov pc, lr
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 8c4defc4f3c4..1e4cbd4e7be9 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -25,7 +25,10 @@ ENTRY(_find_first_zero_bit_le)
25 teq r1, #0 25 teq r1, #0
26 beq 3f 26 beq 3f
27 mov r2, #0 27 mov r2, #0
281: ldrb r3, [r0, r2, lsr #3] 281:
29 ARM( ldrb r3, [r0, r2, lsr #3] )
30 THUMB( lsr r3, r2, #3 )
31 THUMB( ldrb r3, [r0, r3] )
29 eors r3, r3, #0xff @ invert bits 32 eors r3, r3, #0xff @ invert bits
30 bne .L_found @ any now set - found zero bit 33 bne .L_found @ any now set - found zero bit
31 add r2, r2, #8 @ next bit pointer 34 add r2, r2, #8 @ next bit pointer
@@ -44,7 +47,9 @@ ENTRY(_find_next_zero_bit_le)
44 beq 3b 47 beq 3b
45 ands ip, r2, #7 48 ands ip, r2, #7
46 beq 1b @ If new byte, goto old routine 49 beq 1b @ If new byte, goto old routine
47 ldrb r3, [r0, r2, lsr #3] 50 ARM( ldrb r3, [r0, r2, lsr #3] )
51 THUMB( lsr r3, r2, #3 )
52 THUMB( ldrb r3, [r0, r3] )
48 eor r3, r3, #0xff @ now looking for a 1 bit 53 eor r3, r3, #0xff @ now looking for a 1 bit
49 movs r3, r3, lsr ip @ shift off unused bits 54 movs r3, r3, lsr ip @ shift off unused bits
50 bne .L_found 55 bne .L_found
@@ -61,7 +66,10 @@ ENTRY(_find_first_bit_le)
61 teq r1, #0 66 teq r1, #0
62 beq 3f 67 beq 3f
63 mov r2, #0 68 mov r2, #0
641: ldrb r3, [r0, r2, lsr #3] 691:
70 ARM( ldrb r3, [r0, r2, lsr #3] )
71 THUMB( lsr r3, r2, #3 )
72 THUMB( ldrb r3, [r0, r3] )
65 movs r3, r3 73 movs r3, r3
66 bne .L_found @ any now set - found zero bit 74 bne .L_found @ any now set - found zero bit
67 add r2, r2, #8 @ next bit pointer 75 add r2, r2, #8 @ next bit pointer
@@ -80,7 +88,9 @@ ENTRY(_find_next_bit_le)
80 beq 3b 88 beq 3b
81 ands ip, r2, #7 89 ands ip, r2, #7
82 beq 1b @ If new byte, goto old routine 90 beq 1b @ If new byte, goto old routine
83 ldrb r3, [r0, r2, lsr #3] 91 ARM( ldrb r3, [r0, r2, lsr #3] )
92 THUMB( lsr r3, r2, #3 )
93 THUMB( ldrb r3, [r0, r3] )
84 movs r3, r3, lsr ip @ shift off unused bits 94 movs r3, r3, lsr ip @ shift off unused bits
85 bne .L_found 95 bne .L_found
86 orr r2, r2, #7 @ if zero, then no bits here 96 orr r2, r2, #7 @ if zero, then no bits here
@@ -95,7 +105,9 @@ ENTRY(_find_first_zero_bit_be)
95 beq 3f 105 beq 3f
96 mov r2, #0 106 mov r2, #0
971: eor r3, r2, #0x18 @ big endian byte ordering 1071: eor r3, r2, #0x18 @ big endian byte ordering
98 ldrb r3, [r0, r3, lsr #3] 108 ARM( ldrb r3, [r0, r3, lsr #3] )
109 THUMB( lsr r3, #3 )
110 THUMB( ldrb r3, [r0, r3] )
99 eors r3, r3, #0xff @ invert bits 111 eors r3, r3, #0xff @ invert bits
100 bne .L_found @ any now set - found zero bit 112 bne .L_found @ any now set - found zero bit
101 add r2, r2, #8 @ next bit pointer 113 add r2, r2, #8 @ next bit pointer
@@ -111,7 +123,9 @@ ENTRY(_find_next_zero_bit_be)
111 ands ip, r2, #7 123 ands ip, r2, #7
112 beq 1b @ If new byte, goto old routine 124 beq 1b @ If new byte, goto old routine
113 eor r3, r2, #0x18 @ big endian byte ordering 125 eor r3, r2, #0x18 @ big endian byte ordering
114 ldrb r3, [r0, r3, lsr #3] 126 ARM( ldrb r3, [r0, r3, lsr #3] )
127 THUMB( lsr r3, #3 )
128 THUMB( ldrb r3, [r0, r3] )
115 eor r3, r3, #0xff @ now looking for a 1 bit 129 eor r3, r3, #0xff @ now looking for a 1 bit
116 movs r3, r3, lsr ip @ shift off unused bits 130 movs r3, r3, lsr ip @ shift off unused bits
117 bne .L_found 131 bne .L_found
@@ -125,7 +139,9 @@ ENTRY(_find_first_bit_be)
125 beq 3f 139 beq 3f
126 mov r2, #0 140 mov r2, #0
1271: eor r3, r2, #0x18 @ big endian byte ordering 1411: eor r3, r2, #0x18 @ big endian byte ordering
128 ldrb r3, [r0, r3, lsr #3] 142 ARM( ldrb r3, [r0, r3, lsr #3] )
143 THUMB( lsr r3, #3 )
144 THUMB( ldrb r3, [r0, r3] )
129 movs r3, r3 145 movs r3, r3
130 bne .L_found @ any now set - found zero bit 146 bne .L_found @ any now set - found zero bit
131 add r2, r2, #8 @ next bit pointer 147 add r2, r2, #8 @ next bit pointer
@@ -141,7 +157,9 @@ ENTRY(_find_next_bit_be)
141 ands ip, r2, #7 157 ands ip, r2, #7
142 beq 1b @ If new byte, goto old routine 158 beq 1b @ If new byte, goto old routine
143 eor r3, r2, #0x18 @ big endian byte ordering 159 eor r3, r2, #0x18 @ big endian byte ordering
144 ldrb r3, [r0, r3, lsr #3] 160 ARM( ldrb r3, [r0, r3, lsr #3] )
161 THUMB( lsr r3, #3 )
162 THUMB( ldrb r3, [r0, r3] )
145 movs r3, r3, lsr ip @ shift off unused bits 163 movs r3, r3, lsr ip @ shift off unused bits
146 bne .L_found 164 bne .L_found
147 orr r2, r2, #7 @ if zero, then no bits here 165 orr r2, r2, #7 @ if zero, then no bits here
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 6763088b7607..a1814d927122 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -36,8 +36,13 @@ ENTRY(__get_user_1)
36ENDPROC(__get_user_1) 36ENDPROC(__get_user_1)
37 37
38ENTRY(__get_user_2) 38ENTRY(__get_user_2)
39#ifdef CONFIG_THUMB2_KERNEL
402: ldrbt r2, [r0]
413: ldrbt r3, [r0, #1]
42#else
392: ldrbt r2, [r0], #1 432: ldrbt r2, [r0], #1
403: ldrbt r3, [r0] 443: ldrbt r3, [r0]
45#endif
41#ifndef __ARMEB__ 46#ifndef __ARMEB__
42 orr r2, r2, r3, lsl #8 47 orr r2, r2, r3, lsl #8
43#else 48#else
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index d6585612c86b..ff4f71b579ee 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -75,7 +75,10 @@ ENTRY(__raw_writesw)
75#endif 75#endif
76 76
77.Loutsw_noalign: 77.Loutsw_noalign:
78 ldr r3, [r1, -r3]! 78 ARM( ldr r3, [r1, -r3]! )
79 THUMB( rsb r3, r3, #0 )
80 THUMB( ldr r3, [r1, r3] )
81 THUMB( sub r1, r3 )
79 subcs r2, r2, #1 82 subcs r2, r2, #1
80 bcs 2f 83 bcs 2f
81 subs r2, r2, #2 84 subs r2, r2, #2
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
index 99ea338bf87c..f83d449141f7 100644
--- a/arch/arm/lib/lshrdi3.S
+++ b/arch/arm/lib/lshrdi3.S
@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsr)
43 rsb ip, r2, #32 43 rsb ip, r2, #32
44 movmi al, al, lsr r2 44 movmi al, al, lsr r2
45 movpl al, ah, lsr r3 45 movpl al, ah, lsr r3
46 orrmi al, al, ah, lsl ip 46 ARM( orrmi al, al, ah, lsl ip )
47 THUMB( lslmi r3, ah, ip )
48 THUMB( orrmi al, al, r3 )
47 mov ah, ah, lsr r2 49 mov ah, ah, lsr r2
48 mov pc, lr 50 mov pc, lr
49 51
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index e0d002641d3f..a9b9e2287a09 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -13,8 +13,11 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15 15
16#define LDR1W_SHIFT 0
17#define STR1W_SHIFT 0
18
16 .macro ldr1w ptr reg abort 19 .macro ldr1w ptr reg abort
17 ldr \reg, [\ptr], #4 20 W(ldr) \reg, [\ptr], #4
18 .endm 21 .endm
19 22
20 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort 23 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
@@ -30,7 +33,7 @@
30 .endm 33 .endm
31 34
32 .macro str1w ptr reg abort 35 .macro str1w ptr reg abort
33 str \reg, [\ptr], #4 36 W(str) \reg, [\ptr], #4
34 .endm 37 .endm
35 38
36 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 39 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 12549187088c..5025c863713d 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -75,24 +75,24 @@ ENTRY(memmove)
75 addne pc, pc, ip @ C is always clear here 75 addne pc, pc, ip @ C is always clear here
76 b 7f 76 b 7f
776: nop 776: nop
78 ldr r3, [r1, #-4]! 78 W(ldr) r3, [r1, #-4]!
79 ldr r4, [r1, #-4]! 79 W(ldr) r4, [r1, #-4]!
80 ldr r5, [r1, #-4]! 80 W(ldr) r5, [r1, #-4]!
81 ldr r6, [r1, #-4]! 81 W(ldr) r6, [r1, #-4]!
82 ldr r7, [r1, #-4]! 82 W(ldr) r7, [r1, #-4]!
83 ldr r8, [r1, #-4]! 83 W(ldr) r8, [r1, #-4]!
84 ldr lr, [r1, #-4]! 84 W(ldr) lr, [r1, #-4]!
85 85
86 add pc, pc, ip 86 add pc, pc, ip
87 nop 87 nop
88 nop 88 nop
89 str r3, [r0, #-4]! 89 W(str) r3, [r0, #-4]!
90 str r4, [r0, #-4]! 90 W(str) r4, [r0, #-4]!
91 str r5, [r0, #-4]! 91 W(str) r5, [r0, #-4]!
92 str r6, [r0, #-4]! 92 W(str) r6, [r0, #-4]!
93 str r7, [r0, #-4]! 93 W(str) r7, [r0, #-4]!
94 str r8, [r0, #-4]! 94 W(str) r8, [r0, #-4]!
95 str lr, [r0, #-4]! 95 W(str) lr, [r0, #-4]!
96 96
97 CALGN( bcs 2b ) 97 CALGN( bcs 2b )
98 98
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 864f3c1c4f18..02fedbf07c0d 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -37,6 +37,15 @@ ENDPROC(__put_user_1)
37 37
38ENTRY(__put_user_2) 38ENTRY(__put_user_2)
39 mov ip, r2, lsr #8 39 mov ip, r2, lsr #8
40#ifdef CONFIG_THUMB2_KERNEL
41#ifndef __ARMEB__
422: strbt r2, [r0]
433: strbt ip, [r0, #1]
44#else
452: strbt ip, [r0]
463: strbt r2, [r0, #1]
47#endif
48#else /* !CONFIG_THUMB2_KERNEL */
40#ifndef __ARMEB__ 49#ifndef __ARMEB__
412: strbt r2, [r0], #1 502: strbt r2, [r0], #1
423: strbt ip, [r0] 513: strbt ip, [r0]
@@ -44,6 +53,7 @@ ENTRY(__put_user_2)
442: strbt ip, [r0], #1 532: strbt ip, [r0], #1
453: strbt r2, [r0] 543: strbt r2, [r0]
46#endif 55#endif
56#endif /* CONFIG_THUMB2_KERNEL */
47 mov r0, #0 57 mov r0, #0
48 mov pc, lr 58 mov pc, lr
49ENDPROC(__put_user_2) 59ENDPROC(__put_user_2)
@@ -55,8 +65,13 @@ ENTRY(__put_user_4)
55ENDPROC(__put_user_4) 65ENDPROC(__put_user_4)
56 66
57ENTRY(__put_user_8) 67ENTRY(__put_user_8)
68#ifdef CONFIG_THUMB2_KERNEL
695: strt r2, [r0]
706: strt r3, [r0, #4]
71#else
585: strt r2, [r0], #4 725: strt r2, [r0], #4
596: strt r3, [r0] 736: strt r3, [r0]
74#endif
60 mov r0, #0 75 mov r0, #0
61 mov pc, lr 76 mov pc, lr
62ENDPROC(__put_user_8) 77ENDPROC(__put_user_8)
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
index a16fb208c841..09b548cac1a4 100644
--- a/arch/arm/lib/sha1.S
+++ b/arch/arm/lib/sha1.S
@@ -187,6 +187,7 @@ ENTRY(sha_transform)
187 187
188ENDPROC(sha_transform) 188ENDPROC(sha_transform)
189 189
190 .align 2
190.L_sha_K: 191.L_sha_K:
191 .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 192 .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
192 193
@@ -195,6 +196,7 @@ ENDPROC(sha_transform)
195 * void sha_init(__u32 *buf) 196 * void sha_init(__u32 *buf)
196 */ 197 */
197 198
199 .align 2
198.L_sha_initial_digest: 200.L_sha_initial_digest:
199 .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 201 .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
200 202
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S
index 330373c26dd9..1c9814f346c6 100644
--- a/arch/arm/lib/strncpy_from_user.S
+++ b/arch/arm/lib/strncpy_from_user.S
@@ -23,7 +23,7 @@
23ENTRY(__strncpy_from_user) 23ENTRY(__strncpy_from_user)
24 mov ip, r1 24 mov ip, r1
251: subs r2, r2, #1 251: subs r2, r2, #1
26USER( ldrplbt r3, [r1], #1) 26 ldrusr r3, r1, 1, pl
27 bmi 2f 27 bmi 2f
28 strb r3, [r0], #1 28 strb r3, [r0], #1
29 teq r3, #0 29 teq r3, #0
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S
index 90bb9d020836..7855b2906659 100644
--- a/arch/arm/lib/strnlen_user.S
+++ b/arch/arm/lib/strnlen_user.S
@@ -23,7 +23,7 @@
23ENTRY(__strnlen_user) 23ENTRY(__strnlen_user)
24 mov r2, r0 24 mov r2, r0
251: 251:
26USER( ldrbt r3, [r0], #1) 26 ldrusr r3, r0, 1
27 teq r3, #0 27 teq r3, #0
28 beq 2f 28 beq 2f
29 subs r1, r1, #1 29 subs r1, r1, #1
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 323b47f2b52f..a24d824c428b 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -23,6 +23,12 @@ config ARCH_AT91SAM9261
23 select GENERIC_TIME 23 select GENERIC_TIME
24 select GENERIC_CLOCKEVENTS 24 select GENERIC_CLOCKEVENTS
25 25
26config ARCH_AT91SAM9G10
27 bool "AT91SAM9G10"
28 select CPU_ARM926T
29 select GENERIC_TIME
30 select GENERIC_CLOCKEVENTS
31
26config ARCH_AT91SAM9263 32config ARCH_AT91SAM9263
27 bool "AT91SAM9263" 33 bool "AT91SAM9263"
28 select CPU_ARM926T 34 select CPU_ARM926T
@@ -41,6 +47,12 @@ config ARCH_AT91SAM9G20
41 select GENERIC_TIME 47 select GENERIC_TIME
42 select GENERIC_CLOCKEVENTS 48 select GENERIC_CLOCKEVENTS
43 49
50config ARCH_AT91SAM9G45
51 bool "AT91SAM9G45"
52 select CPU_ARM926T
53 select GENERIC_TIME
54 select GENERIC_CLOCKEVENTS
55
44config ARCH_AT91CAP9 56config ARCH_AT91CAP9
45 bool "AT91CAP9" 57 bool "AT91CAP9"
46 select CPU_ARM926T 58 select CPU_ARM926T
@@ -144,6 +156,13 @@ config MACH_YL9200
144 help 156 help
145 Select this if you are using the ucDragon YL-9200 board. 157 Select this if you are using the ucDragon YL-9200 board.
146 158
159config MACH_CPUAT91
160 bool "Eukrea CPUAT91"
161 depends on ARCH_AT91RM9200
162 help
163 Select this if you are using the Eukrea Electromatique's
164 CPUAT91 board <http://www.eukrea.com/>.
165
147endif 166endif
148 167
149# ---------------------------------------------------------- 168# ----------------------------------------------------------
@@ -205,6 +224,13 @@ config MACH_QIL_A9260
205 Select this if you are using a Calao Systems QIL-A9260 Board. 224 Select this if you are using a Calao Systems QIL-A9260 Board.
206 <http://www.calao-systems.com> 225 <http://www.calao-systems.com>
207 226
227config MACH_CPU9260
228 bool "Eukrea CPU9260 board"
229 depends on ARCH_AT91SAM9260
230 help
231 Select this if you are using a Eukrea Electromatique's
232 CPU9260 Board <http://www.eukrea.com/>
233
208endif 234endif
209 235
210# ---------------------------------------------------------- 236# ----------------------------------------------------------
@@ -224,6 +250,21 @@ endif
224 250
225# ---------------------------------------------------------- 251# ----------------------------------------------------------
226 252
253if ARCH_AT91SAM9G10
254
255comment "AT91SAM9G10 Board Type"
256
257config MACH_AT91SAM9G10EK
258 bool "Atmel AT91SAM9G10-EK Evaluation Kit"
259 depends on ARCH_AT91SAM9G10
260 help
261 Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
262 <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
263
264endif
265
266# ----------------------------------------------------------
267
227if ARCH_AT91SAM9263 268if ARCH_AT91SAM9263
228 269
229comment "AT91SAM9263 Board Type" 270comment "AT91SAM9263 Board Type"
@@ -276,6 +317,29 @@ config MACH_AT91SAM9G20EK
276 help 317 help
277 Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. 318 Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
278 319
320config MACH_CPU9G20
321 bool "Eukrea CPU9G20 board"
322 depends on ARCH_AT91SAM9G20
323 help
324 Select this if you are using a Eukrea Electromatique's
325 CPU9G20 Board <http://www.eukrea.com/>
326
327endif
328
329# ----------------------------------------------------------
330
331if ARCH_AT91SAM9G45
332
333comment "AT91SAM9G45 Board Type"
334
335config MACH_AT91SAM9G45EKES
336 bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
337 depends on ARCH_AT91SAM9G45
338 help
339 Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
340 "ES" at the end of the name means that this board is an
341 Engineering Sample.
342
279endif 343endif
280 344
281# ---------------------------------------------------------- 345# ----------------------------------------------------------
@@ -315,13 +379,13 @@ comment "AT91 Board Options"
315 379
316config MTD_AT91_DATAFLASH_CARD 380config MTD_AT91_DATAFLASH_CARD
317 bool "Enable DataFlash Card support" 381 bool "Enable DataFlash Card support"
318 depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926) 382 depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926)
319 help 383 help
320 Enable support for the DataFlash card. 384 Enable support for the DataFlash card.
321 385
322config MTD_NAND_ATMEL_BUSWIDTH_16 386config MTD_NAND_ATMEL_BUSWIDTH_16
323 bool "Enable 16-bit data bus interface to NAND flash" 387 bool "Enable 16-bit data bus interface to NAND flash"
324 depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK) 388 depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
325 help 389 help
326 On AT91SAM926x boards both types of NAND flash can be present 390 On AT91SAM926x boards both types of NAND flash can be present
327 (8 and 16 bit data bus width). 391 (8 and 16 bit data bus width).
@@ -383,7 +447,7 @@ config AT91_EARLY_USART2
383 447
384config AT91_EARLY_USART3 448config AT91_EARLY_USART3
385 bool "USART3" 449 bool "USART3"
386 depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20) 450 depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45)
387 451
388config AT91_EARLY_USART4 452config AT91_EARLY_USART4
389 bool "USART4" 453 bool "USART4"
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c69ff237fd14..a6ed015d82ed 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -13,9 +13,11 @@ obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
13obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o 13obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
14obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o 14obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
15obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o 15obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
16obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
16obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o 17obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
17obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o 18obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
18obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o 19obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
20 obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
19obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o 21obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
20obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o 22obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
21 23
@@ -32,6 +34,7 @@ obj-$(CONFIG_MACH_KAFA) += board-kafa.o
32obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o 34obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
33obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o 35obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o
34obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o 36obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o
37obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o
35 38
36# AT91SAM9260 board-specific support 39# AT91SAM9260 board-specific support
37obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o 40obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -40,9 +43,11 @@ obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o
40obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o 43obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o
41obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o 44obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o
42obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o 45obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o
46obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o
43 47
44# AT91SAM9261 board-specific support 48# AT91SAM9261 board-specific support
45obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o 49obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
50obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o
46 51
47# AT91SAM9263 board-specific support 52# AT91SAM9263 board-specific support
48obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o 53obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
@@ -54,6 +59,10 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
54 59
55# AT91SAM9G20 board-specific support 60# AT91SAM9G20 board-specific support
56obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o 61obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
62obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
63
64# AT91SAM9G45 board-specific support
65obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
57 66
58# AT91CAP9 board-specific support 67# AT91CAP9 board-specific support
59obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o 68obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index 071a2506a69f..3462b815054a 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -7,6 +7,10 @@ ifeq ($(CONFIG_ARCH_AT91CAP9),y)
7 zreladdr-y := 0x70008000 7 zreladdr-y := 0x70008000
8params_phys-y := 0x70000100 8params_phys-y := 0x70000100
9initrd_phys-y := 0x70410000 9initrd_phys-y := 0x70410000
10else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
11 zreladdr-y := 0x70008000
12params_phys-y := 0x70000100
13initrd_phys-y := 0x70410000
10else 14else
11 zreladdr-y := 0x20008000 15 zreladdr-y := 0x20008000
12params_phys-y := 0x20000100 16params_phys-y := 0x20000100
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index d74c9ac007e7..ee4ea0e720cf 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -1113,6 +1113,122 @@ void __init at91_set_serial_console(unsigned portnr) {}
1113void __init at91_add_device_serial(void) {} 1113void __init at91_add_device_serial(void) {}
1114#endif 1114#endif
1115 1115
1116/* --------------------------------------------------------------------
1117 * CF/IDE
1118 * -------------------------------------------------------------------- */
1119
1120#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \
1121 defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
1122 defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
1123
1124static struct at91_cf_data cf0_data;
1125
1126static struct resource cf0_resources[] = {
1127 [0] = {
1128 .start = AT91_CHIPSELECT_4,
1129 .end = AT91_CHIPSELECT_4 + SZ_256M - 1,
1130 .flags = IORESOURCE_MEM,
1131 }
1132};
1133
1134static struct platform_device cf0_device = {
1135 .id = 0,
1136 .dev = {
1137 .platform_data = &cf0_data,
1138 },
1139 .resource = cf0_resources,
1140 .num_resources = ARRAY_SIZE(cf0_resources),
1141};
1142
1143static struct at91_cf_data cf1_data;
1144
1145static struct resource cf1_resources[] = {
1146 [0] = {
1147 .start = AT91_CHIPSELECT_5,
1148 .end = AT91_CHIPSELECT_5 + SZ_256M - 1,
1149 .flags = IORESOURCE_MEM,
1150 }
1151};
1152
1153static struct platform_device cf1_device = {
1154 .id = 1,
1155 .dev = {
1156 .platform_data = &cf1_data,
1157 },
1158 .resource = cf1_resources,
1159 .num_resources = ARRAY_SIZE(cf1_resources),
1160};
1161
1162void __init at91_add_device_cf(struct at91_cf_data *data)
1163{
1164 struct platform_device *pdev;
1165 unsigned long csa;
1166
1167 if (!data)
1168 return;
1169
1170 csa = at91_sys_read(AT91_MATRIX_EBICSA);
1171
1172 switch (data->chipselect) {
1173 case 4:
1174 at91_set_multi_drive(AT91_PIN_PC8, 0);
1175 at91_set_A_periph(AT91_PIN_PC8, 0);
1176 csa |= AT91_MATRIX_CS4A_SMC_CF1;
1177 cf0_data = *data;
1178 pdev = &cf0_device;
1179 break;
1180 case 5:
1181 at91_set_multi_drive(AT91_PIN_PC9, 0);
1182 at91_set_A_periph(AT91_PIN_PC9, 0);
1183 csa |= AT91_MATRIX_CS5A_SMC_CF2;
1184 cf1_data = *data;
1185 pdev = &cf1_device;
1186 break;
1187 default:
1188 printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
1189 data->chipselect);
1190 return;
1191 }
1192
1193 at91_sys_write(AT91_MATRIX_EBICSA, csa);
1194
1195 if (data->rst_pin) {
1196 at91_set_multi_drive(data->rst_pin, 0);
1197 at91_set_gpio_output(data->rst_pin, 1);
1198 }
1199
1200 if (data->irq_pin) {
1201 at91_set_gpio_input(data->irq_pin, 0);
1202 at91_set_deglitch(data->irq_pin, 1);
1203 }
1204
1205 if (data->det_pin) {
1206 at91_set_gpio_input(data->det_pin, 0);
1207 at91_set_deglitch(data->det_pin, 1);
1208 }
1209
1210 at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */
1211 at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */
1212 at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */
1213 at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */
1214
1215 if (data->flags & AT91_CF_TRUE_IDE)
1216#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
1217 pdev->name = "pata_at91";
1218#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
1219 pdev->name = "at91_ide";
1220#else
1221#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91"
1222#endif
1223 else
1224 pdev->name = "at91_cf";
1225
1226 platform_device_register(pdev);
1227}
1228
1229#else
1230void __init at91_add_device_cf(struct at91_cf_data * data) {}
1231#endif
1116 1232
1117/* -------------------------------------------------------------------- */ 1233/* -------------------------------------------------------------------- */
1118/* 1234/*
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 3acd7d7e6a42..4ecf37996c77 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -16,6 +16,7 @@
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
18#include <asm/mach/map.h> 18#include <asm/mach/map.h>
19#include <mach/cpu.h>
19#include <mach/at91sam9261.h> 20#include <mach/at91sam9261.h>
20#include <mach/at91_pmc.h> 21#include <mach/at91_pmc.h>
21#include <mach/at91_rstc.h> 22#include <mach/at91_rstc.h>
@@ -30,7 +31,11 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
30 .pfn = __phys_to_pfn(AT91_BASE_SYS), 31 .pfn = __phys_to_pfn(AT91_BASE_SYS),
31 .length = SZ_16K, 32 .length = SZ_16K,
32 .type = MT_DEVICE, 33 .type = MT_DEVICE,
33 }, { 34 },
35};
36
37static struct map_desc at91sam9261_sram_desc[] __initdata = {
38 {
34 .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, 39 .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
35 .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), 40 .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE),
36 .length = AT91SAM9261_SRAM_SIZE, 41 .length = AT91SAM9261_SRAM_SIZE,
@@ -38,6 +43,15 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
38 }, 43 },
39}; 44};
40 45
46static struct map_desc at91sam9g10_sram_desc[] __initdata = {
47 {
48 .virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,
49 .pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE),
50 .length = AT91SAM9G10_SRAM_SIZE,
51 .type = MT_DEVICE,
52 },
53};
54
41/* -------------------------------------------------------------------- 55/* --------------------------------------------------------------------
42 * Clocks 56 * Clocks
43 * -------------------------------------------------------------------- */ 57 * -------------------------------------------------------------------- */
@@ -263,6 +277,12 @@ void __init at91sam9261_initialize(unsigned long main_clock)
263 /* Map peripherals */ 277 /* Map peripherals */
264 iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); 278 iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
265 279
280 if (cpu_is_at91sam9g10())
281 iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
282 else
283 iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
284
285
266 at91_arch_reset = at91sam9261_reset; 286 at91_arch_reset = at91sam9261_reset;
267 pm_power_off = at91sam9261_poweroff; 287 pm_power_off = at91sam9261_poweroff;
268 at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) 288 at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index b7f233242315..55719a974276 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -707,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
707 * AC97 707 * AC97
708 * -------------------------------------------------------------------- */ 708 * -------------------------------------------------------------------- */
709 709
710#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) 710#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
711static u64 ac97_dmamask = DMA_BIT_MASK(32); 711static u64 ac97_dmamask = DMA_BIT_MASK(32);
712static struct atmel_ac97_data ac97_data; 712static struct ac97c_platform_data ac97_data;
713 713
714static struct resource ac97_resources[] = { 714static struct resource ac97_resources[] = {
715 [0] = { 715 [0] = {
@@ -725,8 +725,8 @@ static struct resource ac97_resources[] = {
725}; 725};
726 726
727static struct platform_device at91sam9263_ac97_device = { 727static struct platform_device at91sam9263_ac97_device = {
728 .name = "ac97c", 728 .name = "atmel_ac97c",
729 .id = 1, 729 .id = 0,
730 .dev = { 730 .dev = {
731 .dma_mask = &ac97_dmamask, 731 .dma_mask = &ac97_dmamask,
732 .coherent_dma_mask = DMA_BIT_MASK(32), 732 .coherent_dma_mask = DMA_BIT_MASK(32),
@@ -736,7 +736,7 @@ static struct platform_device at91sam9263_ac97_device = {
736 .num_resources = ARRAY_SIZE(ac97_resources), 736 .num_resources = ARRAY_SIZE(ac97_resources),
737}; 737};
738 738
739void __init at91_add_device_ac97(struct atmel_ac97_data *data) 739void __init at91_add_device_ac97(struct ac97c_platform_data *data)
740{ 740{
741 if (!data) 741 if (!data)
742 return; 742 return;
@@ -750,11 +750,11 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data)
750 if (data->reset_pin) 750 if (data->reset_pin)
751 at91_set_gpio_output(data->reset_pin, 0); 751 at91_set_gpio_output(data->reset_pin, 0);
752 752
753 ac97_data = *ek_data; 753 ac97_data = *data;
754 platform_device_register(&at91sam9263_ac97_device); 754 platform_device_register(&at91sam9263_ac97_device);
755} 755}
756#else 756#else
757void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} 757void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
758#endif 758#endif
759 759
760 760
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
new file mode 100644
index 000000000000..85166b7e69a1
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -0,0 +1,360 @@
1/*
2 * Chip-specific setup code for the AT91SAM9G45 family
3 *
4 * Copyright (C) 2009 Atmel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/pm.h>
15
16#include <asm/irq.h>
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <mach/at91sam9g45.h>
20#include <mach/at91_pmc.h>
21#include <mach/at91_rstc.h>
22#include <mach/at91_shdwc.h>
23
24#include "generic.h"
25#include "clock.h"
26
27static struct map_desc at91sam9g45_io_desc[] __initdata = {
28 {
29 .virtual = AT91_VA_BASE_SYS,
30 .pfn = __phys_to_pfn(AT91_BASE_SYS),
31 .length = SZ_16K,
32 .type = MT_DEVICE,
33 }, {
34 .virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
35 .pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
36 .length = AT91SAM9G45_SRAM_SIZE,
37 .type = MT_DEVICE,
38 }
39};
40
41/* --------------------------------------------------------------------
42 * Clocks
43 * -------------------------------------------------------------------- */
44
45/*
46 * The peripheral clocks.
47 */
48static struct clk pioA_clk = {
49 .name = "pioA_clk",
50 .pmc_mask = 1 << AT91SAM9G45_ID_PIOA,
51 .type = CLK_TYPE_PERIPHERAL,
52};
53static struct clk pioB_clk = {
54 .name = "pioB_clk",
55 .pmc_mask = 1 << AT91SAM9G45_ID_PIOB,
56 .type = CLK_TYPE_PERIPHERAL,
57};
58static struct clk pioC_clk = {
59 .name = "pioC_clk",
60 .pmc_mask = 1 << AT91SAM9G45_ID_PIOC,
61 .type = CLK_TYPE_PERIPHERAL,
62};
63static struct clk pioDE_clk = {
64 .name = "pioDE_clk",
65 .pmc_mask = 1 << AT91SAM9G45_ID_PIODE,
66 .type = CLK_TYPE_PERIPHERAL,
67};
68static struct clk usart0_clk = {
69 .name = "usart0_clk",
70 .pmc_mask = 1 << AT91SAM9G45_ID_US0,
71 .type = CLK_TYPE_PERIPHERAL,
72};
73static struct clk usart1_clk = {
74 .name = "usart1_clk",
75 .pmc_mask = 1 << AT91SAM9G45_ID_US1,
76 .type = CLK_TYPE_PERIPHERAL,
77};
78static struct clk usart2_clk = {
79 .name = "usart2_clk",
80 .pmc_mask = 1 << AT91SAM9G45_ID_US2,
81 .type = CLK_TYPE_PERIPHERAL,
82};
83static struct clk usart3_clk = {
84 .name = "usart3_clk",
85 .pmc_mask = 1 << AT91SAM9G45_ID_US3,
86 .type = CLK_TYPE_PERIPHERAL,
87};
88static struct clk mmc0_clk = {
89 .name = "mci0_clk",
90 .pmc_mask = 1 << AT91SAM9G45_ID_MCI0,
91 .type = CLK_TYPE_PERIPHERAL,
92};
93static struct clk twi0_clk = {
94 .name = "twi0_clk",
95 .pmc_mask = 1 << AT91SAM9G45_ID_TWI0,
96 .type = CLK_TYPE_PERIPHERAL,
97};
98static struct clk twi1_clk = {
99 .name = "twi1_clk",
100 .pmc_mask = 1 << AT91SAM9G45_ID_TWI1,
101 .type = CLK_TYPE_PERIPHERAL,
102};
103static struct clk spi0_clk = {
104 .name = "spi0_clk",
105 .pmc_mask = 1 << AT91SAM9G45_ID_SPI0,
106 .type = CLK_TYPE_PERIPHERAL,
107};
108static struct clk spi1_clk = {
109 .name = "spi1_clk",
110 .pmc_mask = 1 << AT91SAM9G45_ID_SPI1,
111 .type = CLK_TYPE_PERIPHERAL,
112};
113static struct clk ssc0_clk = {
114 .name = "ssc0_clk",
115 .pmc_mask = 1 << AT91SAM9G45_ID_SSC0,
116 .type = CLK_TYPE_PERIPHERAL,
117};
118static struct clk ssc1_clk = {
119 .name = "ssc1_clk",
120 .pmc_mask = 1 << AT91SAM9G45_ID_SSC1,
121 .type = CLK_TYPE_PERIPHERAL,
122};
123static struct clk tcb_clk = {
124 .name = "tcb_clk",
125 .pmc_mask = 1 << AT91SAM9G45_ID_TCB,
126 .type = CLK_TYPE_PERIPHERAL,
127};
128static struct clk pwm_clk = {
129 .name = "pwm_clk",
130 .pmc_mask = 1 << AT91SAM9G45_ID_PWMC,
131 .type = CLK_TYPE_PERIPHERAL,
132};
133static struct clk tsc_clk = {
134 .name = "tsc_clk",
135 .pmc_mask = 1 << AT91SAM9G45_ID_TSC,
136 .type = CLK_TYPE_PERIPHERAL,
137};
138static struct clk dma_clk = {
139 .name = "dma_clk",
140 .pmc_mask = 1 << AT91SAM9G45_ID_DMA,
141 .type = CLK_TYPE_PERIPHERAL,
142};
143static struct clk uhphs_clk = {
144 .name = "uhphs_clk",
145 .pmc_mask = 1 << AT91SAM9G45_ID_UHPHS,
146 .type = CLK_TYPE_PERIPHERAL,
147};
148static struct clk lcdc_clk = {
149 .name = "lcdc_clk",
150 .pmc_mask = 1 << AT91SAM9G45_ID_LCDC,
151 .type = CLK_TYPE_PERIPHERAL,
152};
153static struct clk ac97_clk = {
154 .name = "ac97_clk",
155 .pmc_mask = 1 << AT91SAM9G45_ID_AC97C,
156 .type = CLK_TYPE_PERIPHERAL,
157};
158static struct clk macb_clk = {
159 .name = "macb_clk",
160 .pmc_mask = 1 << AT91SAM9G45_ID_EMAC,
161 .type = CLK_TYPE_PERIPHERAL,
162};
163static struct clk isi_clk = {
164 .name = "isi_clk",
165 .pmc_mask = 1 << AT91SAM9G45_ID_ISI,
166 .type = CLK_TYPE_PERIPHERAL,
167};
168static struct clk udphs_clk = {
169 .name = "udphs_clk",
170 .pmc_mask = 1 << AT91SAM9G45_ID_UDPHS,
171 .type = CLK_TYPE_PERIPHERAL,
172};
173static struct clk mmc1_clk = {
174 .name = "mci1_clk",
175 .pmc_mask = 1 << AT91SAM9G45_ID_MCI1,
176 .type = CLK_TYPE_PERIPHERAL,
177};
178
179/* One additional fake clock for ohci */
180static struct clk ohci_clk = {
181 .name = "ohci_clk",
182 .pmc_mask = 0,
183 .type = CLK_TYPE_PERIPHERAL,
184 .parent = &uhphs_clk,
185};
186
187static struct clk *periph_clocks[] __initdata = {
188 &pioA_clk,
189 &pioB_clk,
190 &pioC_clk,
191 &pioDE_clk,
192 &usart0_clk,
193 &usart1_clk,
194 &usart2_clk,
195 &usart3_clk,
196 &mmc0_clk,
197 &twi0_clk,
198 &twi1_clk,
199 &spi0_clk,
200 &spi1_clk,
201 &ssc0_clk,
202 &ssc1_clk,
203 &tcb_clk,
204 &pwm_clk,
205 &tsc_clk,
206 &dma_clk,
207 &uhphs_clk,
208 &lcdc_clk,
209 &ac97_clk,
210 &macb_clk,
211 &isi_clk,
212 &udphs_clk,
213 &mmc1_clk,
214 // irq0
215 &ohci_clk,
216};
217
218/*
219 * The two programmable clocks.
220 * You must configure pin multiplexing to bring these signals out.
221 */
222static struct clk pck0 = {
223 .name = "pck0",
224 .pmc_mask = AT91_PMC_PCK0,
225 .type = CLK_TYPE_PROGRAMMABLE,
226 .id = 0,
227};
228static struct clk pck1 = {
229 .name = "pck1",
230 .pmc_mask = AT91_PMC_PCK1,
231 .type = CLK_TYPE_PROGRAMMABLE,
232 .id = 1,
233};
234
235static void __init at91sam9g45_register_clocks(void)
236{
237 int i;
238
239 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
240 clk_register(periph_clocks[i]);
241
242 clk_register(&pck0);
243 clk_register(&pck1);
244}
245
246/* --------------------------------------------------------------------
247 * GPIO
248 * -------------------------------------------------------------------- */
249
250static struct at91_gpio_bank at91sam9g45_gpio[] = {
251 {
252 .id = AT91SAM9G45_ID_PIOA,
253 .offset = AT91_PIOA,
254 .clock = &pioA_clk,
255 }, {
256 .id = AT91SAM9G45_ID_PIOB,
257 .offset = AT91_PIOB,
258 .clock = &pioB_clk,
259 }, {
260 .id = AT91SAM9G45_ID_PIOC,
261 .offset = AT91_PIOC,
262 .clock = &pioC_clk,
263 }, {
264 .id = AT91SAM9G45_ID_PIODE,
265 .offset = AT91_PIOD,
266 .clock = &pioDE_clk,
267 }, {
268 .id = AT91SAM9G45_ID_PIODE,
269 .offset = AT91_PIOE,
270 .clock = &pioDE_clk,
271 }
272};
273
274static void at91sam9g45_reset(void)
275{
276 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
277}
278
279static void at91sam9g45_poweroff(void)
280{
281 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
282}
283
284
285/* --------------------------------------------------------------------
286 * AT91SAM9G45 processor initialization
287 * -------------------------------------------------------------------- */
288
289void __init at91sam9g45_initialize(unsigned long main_clock)
290{
291 /* Map peripherals */
292 iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
293
294 at91_arch_reset = at91sam9g45_reset;
295 pm_power_off = at91sam9g45_poweroff;
296 at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
297
298 /* Init clock subsystem */
299 at91_clock_init(main_clock);
300
301 /* Register the processor-specific clocks */
302 at91sam9g45_register_clocks();
303
304 /* Register GPIO subsystem */
305 at91_gpio_init(at91sam9g45_gpio, 5);
306}
307
308/* --------------------------------------------------------------------
309 * Interrupt initialization
310 * -------------------------------------------------------------------- */
311
312/*
313 * The default interrupt priority levels (0 = lowest, 7 = highest).
314 */
315static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
316 7, /* Advanced Interrupt Controller (FIQ) */
317 7, /* System Peripherals */
318 1, /* Parallel IO Controller A */
319 1, /* Parallel IO Controller B */
320 1, /* Parallel IO Controller C */
321 1, /* Parallel IO Controller D and E */
322 0,
323 5, /* USART 0 */
324 5, /* USART 1 */
325 5, /* USART 2 */
326 5, /* USART 3 */
327 0, /* Multimedia Card Interface 0 */
328 6, /* Two-Wire Interface 0 */
329 6, /* Two-Wire Interface 1 */
330 5, /* Serial Peripheral Interface 0 */
331 5, /* Serial Peripheral Interface 1 */
332 4, /* Serial Synchronous Controller 0 */
333 4, /* Serial Synchronous Controller 1 */
334 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
335 0, /* Pulse Width Modulation Controller */
336 0, /* Touch Screen Controller */
337 0, /* DMA Controller */
338 2, /* USB Host High Speed port */
339 3, /* LDC Controller */
340 5, /* AC97 Controller */
341 3, /* Ethernet */
342 0, /* Image Sensor Interface */
343 2, /* USB Device High speed port */
344 0,
345 0, /* Multimedia Card Interface 1 */
346 0,
347 0, /* Advanced Interrupt Controller (IRQ0) */
348};
349
350void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
351{
352 if (!priority)
353 priority = at91sam9g45_default_irq_priority;
354
355 /* Initialize the AIC interrupt controller */
356 at91_aic_init(priority);
357
358 /* Enable GPIO interrupts */
359 at91_gpio_irq_setup();
360}
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
new file mode 100644
index 000000000000..d746e8621bc2
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -0,0 +1,1230 @@
1/*
2 * On-Chip devices setup code for the AT91SAM9G45 family
3 *
4 * Copyright (C) 2009 Atmel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12#include <asm/mach/arch.h>
13#include <asm/mach/map.h>
14
15#include <linux/dma-mapping.h>
16#include <linux/platform_device.h>
17#include <linux/i2c-gpio.h>
18
19#include <linux/fb.h>
20#include <video/atmel_lcdc.h>
21
22#include <mach/board.h>
23#include <mach/gpio.h>
24#include <mach/at91sam9g45.h>
25#include <mach/at91sam9g45_matrix.h>
26#include <mach/at91sam9_smc.h>
27
28#include "generic.h"
29
30
31/* --------------------------------------------------------------------
32 * USB Host (OHCI)
33 * -------------------------------------------------------------------- */
34
35#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
36static u64 ohci_dmamask = DMA_BIT_MASK(32);
37static struct at91_usbh_data usbh_ohci_data;
38
39static struct resource usbh_ohci_resources[] = {
40 [0] = {
41 .start = AT91SAM9G45_OHCI_BASE,
42 .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1,
43 .flags = IORESOURCE_MEM,
44 },
45 [1] = {
46 .start = AT91SAM9G45_ID_UHPHS,
47 .end = AT91SAM9G45_ID_UHPHS,
48 .flags = IORESOURCE_IRQ,
49 },
50};
51
52static struct platform_device at91_usbh_ohci_device = {
53 .name = "at91_ohci",
54 .id = -1,
55 .dev = {
56 .dma_mask = &ohci_dmamask,
57 .coherent_dma_mask = DMA_BIT_MASK(32),
58 .platform_data = &usbh_ohci_data,
59 },
60 .resource = usbh_ohci_resources,
61 .num_resources = ARRAY_SIZE(usbh_ohci_resources),
62};
63
64void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
65{
66 int i;
67
68 if (!data)
69 return;
70
71 /* Enable VBus control for UHP ports */
72 for (i = 0; i < data->ports; i++) {
73 if (data->vbus_pin[i])
74 at91_set_gpio_output(data->vbus_pin[i], 0);
75 }
76
77 usbh_ohci_data = *data;
78 platform_device_register(&at91_usbh_ohci_device);
79}
80#else
81void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
82#endif
83
84
85/* --------------------------------------------------------------------
86 * USB HS Device (Gadget)
87 * -------------------------------------------------------------------- */
88
89#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
90static struct resource usba_udc_resources[] = {
91 [0] = {
92 .start = AT91SAM9G45_UDPHS_FIFO,
93 .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1,
94 .flags = IORESOURCE_MEM,
95 },
96 [1] = {
97 .start = AT91SAM9G45_BASE_UDPHS,
98 .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1,
99 .flags = IORESOURCE_MEM,
100 },
101 [2] = {
102 .start = AT91SAM9G45_ID_UDPHS,
103 .end = AT91SAM9G45_ID_UDPHS,
104 .flags = IORESOURCE_IRQ,
105 },
106};
107
108#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
109 [idx] = { \
110 .name = nam, \
111 .index = idx, \
112 .fifo_size = maxpkt, \
113 .nr_banks = maxbk, \
114 .can_dma = dma, \
115 .can_isoc = isoc, \
116 }
117
118static struct usba_ep_data usba_udc_ep[] __initdata = {
119 EP("ep0", 0, 64, 1, 0, 0),
120 EP("ep1", 1, 1024, 2, 1, 1),
121 EP("ep2", 2, 1024, 2, 1, 1),
122 EP("ep3", 3, 1024, 3, 1, 0),
123 EP("ep4", 4, 1024, 3, 1, 0),
124 EP("ep5", 5, 1024, 3, 1, 1),
125 EP("ep6", 6, 1024, 3, 1, 1),
126};
127
128#undef EP
129
130/*
131 * pdata doesn't have room for any endpoints, so we need to
132 * append room for the ones we need right after it.
133 */
134static struct {
135 struct usba_platform_data pdata;
136 struct usba_ep_data ep[7];
137} usba_udc_data;
138
139static struct platform_device at91_usba_udc_device = {
140 .name = "atmel_usba_udc",
141 .id = -1,
142 .dev = {
143 .platform_data = &usba_udc_data.pdata,
144 },
145 .resource = usba_udc_resources,
146 .num_resources = ARRAY_SIZE(usba_udc_resources),
147};
148
149void __init at91_add_device_usba(struct usba_platform_data *data)
150{
151 usba_udc_data.pdata.vbus_pin = -EINVAL;
152 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
153 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
154
155 if (data && data->vbus_pin > 0) {
156 at91_set_gpio_input(data->vbus_pin, 0);
157 at91_set_deglitch(data->vbus_pin, 1);
158 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
159 }
160
161 /* Pullup pin is handled internally by USB device peripheral */
162
163 /* Clocks */
164 at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
165 at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
166
167 platform_device_register(&at91_usba_udc_device);
168}
169#else
170void __init at91_add_device_usba(struct usba_platform_data *data) {}
171#endif
172
173
174/* --------------------------------------------------------------------
175 * Ethernet
176 * -------------------------------------------------------------------- */
177
178#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
179static u64 eth_dmamask = DMA_BIT_MASK(32);
180static struct at91_eth_data eth_data;
181
182static struct resource eth_resources[] = {
183 [0] = {
184 .start = AT91SAM9G45_BASE_EMAC,
185 .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1,
186 .flags = IORESOURCE_MEM,
187 },
188 [1] = {
189 .start = AT91SAM9G45_ID_EMAC,
190 .end = AT91SAM9G45_ID_EMAC,
191 .flags = IORESOURCE_IRQ,
192 },
193};
194
195static struct platform_device at91sam9g45_eth_device = {
196 .name = "macb",
197 .id = -1,
198 .dev = {
199 .dma_mask = &eth_dmamask,
200 .coherent_dma_mask = DMA_BIT_MASK(32),
201 .platform_data = &eth_data,
202 },
203 .resource = eth_resources,
204 .num_resources = ARRAY_SIZE(eth_resources),
205};
206
207void __init at91_add_device_eth(struct at91_eth_data *data)
208{
209 if (!data)
210 return;
211
212 if (data->phy_irq_pin) {
213 at91_set_gpio_input(data->phy_irq_pin, 0);
214 at91_set_deglitch(data->phy_irq_pin, 1);
215 }
216
217 /* Pins used for MII and RMII */
218 at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */
219 at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */
220 at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */
221 at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */
222 at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */
223 at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */
224 at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */
225 at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */
226 at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */
227 at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */
228
229 if (!data->is_rmii) {
230 at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */
231 at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */
232 at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */
233 at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */
234 at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */
235 at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */
236 at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */
237 at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */
238 }
239
240 eth_data = *data;
241 platform_device_register(&at91sam9g45_eth_device);
242}
243#else
244void __init at91_add_device_eth(struct at91_eth_data *data) {}
245#endif
246
247
248/* --------------------------------------------------------------------
249 * NAND / SmartMedia
250 * -------------------------------------------------------------------- */
251
252#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
253static struct atmel_nand_data nand_data;
254
255#define NAND_BASE AT91_CHIPSELECT_3
256
257static struct resource nand_resources[] = {
258 [0] = {
259 .start = NAND_BASE,
260 .end = NAND_BASE + SZ_256M - 1,
261 .flags = IORESOURCE_MEM,
262 },
263 [1] = {
264 .start = AT91_BASE_SYS + AT91_ECC,
265 .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
266 .flags = IORESOURCE_MEM,
267 }
268};
269
270static struct platform_device at91sam9g45_nand_device = {
271 .name = "atmel_nand",
272 .id = -1,
273 .dev = {
274 .platform_data = &nand_data,
275 },
276 .resource = nand_resources,
277 .num_resources = ARRAY_SIZE(nand_resources),
278};
279
280void __init at91_add_device_nand(struct atmel_nand_data *data)
281{
282 unsigned long csa;
283
284 if (!data)
285 return;
286
287 csa = at91_sys_read(AT91_MATRIX_EBICSA);
288 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
289
290 /* enable pin */
291 if (data->enable_pin)
292 at91_set_gpio_output(data->enable_pin, 1);
293
294 /* ready/busy pin */
295 if (data->rdy_pin)
296 at91_set_gpio_input(data->rdy_pin, 1);
297
298 /* card detect pin */
299 if (data->det_pin)
300 at91_set_gpio_input(data->det_pin, 1);
301
302 nand_data = *data;
303 platform_device_register(&at91sam9g45_nand_device);
304}
305#else
306void __init at91_add_device_nand(struct atmel_nand_data *data) {}
307#endif
308
309
310/* --------------------------------------------------------------------
311 * TWI (i2c)
312 * -------------------------------------------------------------------- */
313
314/*
315 * Prefer the GPIO code since the TWI controller isn't robust
316 * (gets overruns and underruns under load) and can only issue
317 * repeated STARTs in one scenario (the driver doesn't yet handle them).
318 */
319#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
320static struct i2c_gpio_platform_data pdata_i2c0 = {
321 .sda_pin = AT91_PIN_PA20,
322 .sda_is_open_drain = 1,
323 .scl_pin = AT91_PIN_PA21,
324 .scl_is_open_drain = 1,
325 .udelay = 2, /* ~100 kHz */
326};
327
328static struct platform_device at91sam9g45_twi0_device = {
329 .name = "i2c-gpio",
330 .id = 0,
331 .dev.platform_data = &pdata_i2c0,
332};
333
334static struct i2c_gpio_platform_data pdata_i2c1 = {
335 .sda_pin = AT91_PIN_PB10,
336 .sda_is_open_drain = 1,
337 .scl_pin = AT91_PIN_PB11,
338 .scl_is_open_drain = 1,
339 .udelay = 2, /* ~100 kHz */
340};
341
342static struct platform_device at91sam9g45_twi1_device = {
343 .name = "i2c-gpio",
344 .id = 1,
345 .dev.platform_data = &pdata_i2c1,
346};
347
348void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
349{
350 i2c_register_board_info(i2c_id, devices, nr_devices);
351
352 if (i2c_id == 0) {
353 at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */
354 at91_set_multi_drive(AT91_PIN_PA20, 1);
355
356 at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */
357 at91_set_multi_drive(AT91_PIN_PA21, 1);
358
359 platform_device_register(&at91sam9g45_twi0_device);
360 } else {
361 at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */
362 at91_set_multi_drive(AT91_PIN_PB10, 1);
363
364 at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */
365 at91_set_multi_drive(AT91_PIN_PB11, 1);
366
367 platform_device_register(&at91sam9g45_twi1_device);
368 }
369}
370
371#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
372static struct resource twi0_resources[] = {
373 [0] = {
374 .start = AT91SAM9G45_BASE_TWI0,
375 .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1,
376 .flags = IORESOURCE_MEM,
377 },
378 [1] = {
379 .start = AT91SAM9G45_ID_TWI0,
380 .end = AT91SAM9G45_ID_TWI0,
381 .flags = IORESOURCE_IRQ,
382 },
383};
384
385static struct platform_device at91sam9g45_twi0_device = {
386 .name = "at91_i2c",
387 .id = 0,
388 .resource = twi0_resources,
389 .num_resources = ARRAY_SIZE(twi0_resources),
390};
391
392static struct resource twi1_resources[] = {
393 [0] = {
394 .start = AT91SAM9G45_BASE_TWI1,
395 .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1,
396 .flags = IORESOURCE_MEM,
397 },
398 [1] = {
399 .start = AT91SAM9G45_ID_TWI1,
400 .end = AT91SAM9G45_ID_TWI1,
401 .flags = IORESOURCE_IRQ,
402 },
403};
404
405static struct platform_device at91sam9g45_twi1_device = {
406 .name = "at91_i2c",
407 .id = 1,
408 .resource = twi1_resources,
409 .num_resources = ARRAY_SIZE(twi1_resources),
410};
411
412void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
413{
414 i2c_register_board_info(i2c_id, devices, nr_devices);
415
416 /* pins used for TWI interface */
417 if (i2c_id == 0) {
418 at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */
419 at91_set_multi_drive(AT91_PIN_PA20, 1);
420
421 at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */
422 at91_set_multi_drive(AT91_PIN_PA21, 1);
423
424 platform_device_register(&at91sam9g45_twi0_device);
425 } else {
426 at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */
427 at91_set_multi_drive(AT91_PIN_PB10, 1);
428
429 at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */
430 at91_set_multi_drive(AT91_PIN_PB11, 1);
431
432 platform_device_register(&at91sam9g45_twi1_device);
433 }
434}
435#else
436void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {}
437#endif
438
439
440/* --------------------------------------------------------------------
441 * SPI
442 * -------------------------------------------------------------------- */
443
444#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
445static u64 spi_dmamask = DMA_BIT_MASK(32);
446
447static struct resource spi0_resources[] = {
448 [0] = {
449 .start = AT91SAM9G45_BASE_SPI0,
450 .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
451 .flags = IORESOURCE_MEM,
452 },
453 [1] = {
454 .start = AT91SAM9G45_ID_SPI0,
455 .end = AT91SAM9G45_ID_SPI0,
456 .flags = IORESOURCE_IRQ,
457 },
458};
459
460static struct platform_device at91sam9g45_spi0_device = {
461 .name = "atmel_spi",
462 .id = 0,
463 .dev = {
464 .dma_mask = &spi_dmamask,
465 .coherent_dma_mask = DMA_BIT_MASK(32),
466 },
467 .resource = spi0_resources,
468 .num_resources = ARRAY_SIZE(spi0_resources),
469};
470
471static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
472
473static struct resource spi1_resources[] = {
474 [0] = {
475 .start = AT91SAM9G45_BASE_SPI1,
476 .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
477 .flags = IORESOURCE_MEM,
478 },
479 [1] = {
480 .start = AT91SAM9G45_ID_SPI1,
481 .end = AT91SAM9G45_ID_SPI1,
482 .flags = IORESOURCE_IRQ,
483 },
484};
485
486static struct platform_device at91sam9g45_spi1_device = {
487 .name = "atmel_spi",
488 .id = 1,
489 .dev = {
490 .dma_mask = &spi_dmamask,
491 .coherent_dma_mask = DMA_BIT_MASK(32),
492 },
493 .resource = spi1_resources,
494 .num_resources = ARRAY_SIZE(spi1_resources),
495};
496
497static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
498
499void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
500{
501 int i;
502 unsigned long cs_pin;
503 short enable_spi0 = 0;
504 short enable_spi1 = 0;
505
506 /* Choose SPI chip-selects */
507 for (i = 0; i < nr_devices; i++) {
508 if (devices[i].controller_data)
509 cs_pin = (unsigned long) devices[i].controller_data;
510 else if (devices[i].bus_num == 0)
511 cs_pin = spi0_standard_cs[devices[i].chip_select];
512 else
513 cs_pin = spi1_standard_cs[devices[i].chip_select];
514
515 if (devices[i].bus_num == 0)
516 enable_spi0 = 1;
517 else
518 enable_spi1 = 1;
519
520 /* enable chip-select pin */
521 at91_set_gpio_output(cs_pin, 1);
522
523 /* pass chip-select pin to driver */
524 devices[i].controller_data = (void *) cs_pin;
525 }
526
527 spi_register_board_info(devices, nr_devices);
528
529 /* Configure SPI bus(es) */
530 if (enable_spi0) {
531 at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */
532 at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */
533 at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */
534
535 at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk");
536 platform_device_register(&at91sam9g45_spi0_device);
537 }
538 if (enable_spi1) {
539 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */
540 at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */
541 at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */
542
543 at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk");
544 platform_device_register(&at91sam9g45_spi1_device);
545 }
546}
547#else
548void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
549#endif
550
551
552/* --------------------------------------------------------------------
553 * LCD Controller
554 * -------------------------------------------------------------------- */
555
556#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
557static u64 lcdc_dmamask = DMA_BIT_MASK(32);
558static struct atmel_lcdfb_info lcdc_data;
559
560static struct resource lcdc_resources[] = {
561 [0] = {
562 .start = AT91SAM9G45_LCDC_BASE,
563 .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
564 .flags = IORESOURCE_MEM,
565 },
566 [1] = {
567 .start = AT91SAM9G45_ID_LCDC,
568 .end = AT91SAM9G45_ID_LCDC,
569 .flags = IORESOURCE_IRQ,
570 },
571};
572
573static struct platform_device at91_lcdc_device = {
574 .name = "atmel_lcdfb",
575 .id = 0,
576 .dev = {
577 .dma_mask = &lcdc_dmamask,
578 .coherent_dma_mask = DMA_BIT_MASK(32),
579 .platform_data = &lcdc_data,
580 },
581 .resource = lcdc_resources,
582 .num_resources = ARRAY_SIZE(lcdc_resources),
583};
584
585void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
586{
587 if (!data)
588 return;
589
590 at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
591
592 at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
593 at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
594 at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
595 at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
596 at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
597 at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
598 at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
599 at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
600 at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */
601 at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */
602 at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */
603 at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */
604 at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */
605 at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */
606 at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */
607 at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */
608 at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */
609 at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */
610 at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */
611 at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */
612 at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */
613 at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */
614 at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */
615 at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */
616 at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */
617 at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */
618 at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */
619 at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */
620 at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */
621
622 lcdc_data = *data;
623 platform_device_register(&at91_lcdc_device);
624}
625#else
626void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
627#endif
628
629
630/* --------------------------------------------------------------------
631 * Timer/Counter block
632 * -------------------------------------------------------------------- */
633
634#ifdef CONFIG_ATMEL_TCLIB
635static struct resource tcb0_resources[] = {
636 [0] = {
637 .start = AT91SAM9G45_BASE_TCB0,
638 .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
639 .flags = IORESOURCE_MEM,
640 },
641 [1] = {
642 .start = AT91SAM9G45_ID_TCB,
643 .end = AT91SAM9G45_ID_TCB,
644 .flags = IORESOURCE_IRQ,
645 },
646};
647
648static struct platform_device at91sam9g45_tcb0_device = {
649 .name = "atmel_tcb",
650 .id = 0,
651 .resource = tcb0_resources,
652 .num_resources = ARRAY_SIZE(tcb0_resources),
653};
654
655/* TCB1 begins with TC3 */
656static struct resource tcb1_resources[] = {
657 [0] = {
658 .start = AT91SAM9G45_BASE_TCB1,
659 .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
660 .flags = IORESOURCE_MEM,
661 },
662 [1] = {
663 .start = AT91SAM9G45_ID_TCB,
664 .end = AT91SAM9G45_ID_TCB,
665 .flags = IORESOURCE_IRQ,
666 },
667};
668
669static struct platform_device at91sam9g45_tcb1_device = {
670 .name = "atmel_tcb",
671 .id = 1,
672 .resource = tcb1_resources,
673 .num_resources = ARRAY_SIZE(tcb1_resources),
674};
675
676static void __init at91_add_device_tc(void)
677{
678 /* this chip has one clock and irq for all six TC channels */
679 at91_clock_associate("tcb_clk", &at91sam9g45_tcb0_device.dev, "t0_clk");
680 platform_device_register(&at91sam9g45_tcb0_device);
681 at91_clock_associate("tcb_clk", &at91sam9g45_tcb1_device.dev, "t0_clk");
682 platform_device_register(&at91sam9g45_tcb1_device);
683}
684#else
685static void __init at91_add_device_tc(void) { }
686#endif
687
688
689/* --------------------------------------------------------------------
690 * RTC
691 * -------------------------------------------------------------------- */
692
693#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
694static struct platform_device at91sam9g45_rtc_device = {
695 .name = "at91_rtc",
696 .id = -1,
697 .num_resources = 0,
698};
699
700static void __init at91_add_device_rtc(void)
701{
702 platform_device_register(&at91sam9g45_rtc_device);
703}
704#else
705static void __init at91_add_device_rtc(void) {}
706#endif
707
708
709/* --------------------------------------------------------------------
710 * RTT
711 * -------------------------------------------------------------------- */
712
713static struct resource rtt_resources[] = {
714 {
715 .start = AT91_BASE_SYS + AT91_RTT,
716 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
717 .flags = IORESOURCE_MEM,
718 }
719};
720
721static struct platform_device at91sam9g45_rtt_device = {
722 .name = "at91_rtt",
723 .id = 0,
724 .resource = rtt_resources,
725 .num_resources = ARRAY_SIZE(rtt_resources),
726};
727
728static void __init at91_add_device_rtt(void)
729{
730 platform_device_register(&at91sam9g45_rtt_device);
731}
732
733
734/* --------------------------------------------------------------------
735 * Watchdog
736 * -------------------------------------------------------------------- */
737
738#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
739static struct platform_device at91sam9g45_wdt_device = {
740 .name = "at91_wdt",
741 .id = -1,
742 .num_resources = 0,
743};
744
745static void __init at91_add_device_watchdog(void)
746{
747 platform_device_register(&at91sam9g45_wdt_device);
748}
749#else
750static void __init at91_add_device_watchdog(void) {}
751#endif
752
753
754/* --------------------------------------------------------------------
755 * PWM
756 * --------------------------------------------------------------------*/
757
758#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
759static u32 pwm_mask;
760
761static struct resource pwm_resources[] = {
762 [0] = {
763 .start = AT91SAM9G45_BASE_PWMC,
764 .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
765 .flags = IORESOURCE_MEM,
766 },
767 [1] = {
768 .start = AT91SAM9G45_ID_PWMC,
769 .end = AT91SAM9G45_ID_PWMC,
770 .flags = IORESOURCE_IRQ,
771 },
772};
773
774static struct platform_device at91sam9g45_pwm0_device = {
775 .name = "atmel_pwm",
776 .id = -1,
777 .dev = {
778 .platform_data = &pwm_mask,
779 },
780 .resource = pwm_resources,
781 .num_resources = ARRAY_SIZE(pwm_resources),
782};
783
784void __init at91_add_device_pwm(u32 mask)
785{
786 if (mask & (1 << AT91_PWM0))
787 at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */
788
789 if (mask & (1 << AT91_PWM1))
790 at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */
791
792 if (mask & (1 << AT91_PWM2))
793 at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */
794
795 if (mask & (1 << AT91_PWM3))
796 at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */
797
798 pwm_mask = mask;
799
800 platform_device_register(&at91sam9g45_pwm0_device);
801}
802#else
803void __init at91_add_device_pwm(u32 mask) {}
804#endif
805
806
807/* --------------------------------------------------------------------
808 * SSC -- Synchronous Serial Controller
809 * -------------------------------------------------------------------- */
810
811#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
812static u64 ssc0_dmamask = DMA_BIT_MASK(32);
813
814static struct resource ssc0_resources[] = {
815 [0] = {
816 .start = AT91SAM9G45_BASE_SSC0,
817 .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
818 .flags = IORESOURCE_MEM,
819 },
820 [1] = {
821 .start = AT91SAM9G45_ID_SSC0,
822 .end = AT91SAM9G45_ID_SSC0,
823 .flags = IORESOURCE_IRQ,
824 },
825};
826
827static struct platform_device at91sam9g45_ssc0_device = {
828 .name = "ssc",
829 .id = 0,
830 .dev = {
831 .dma_mask = &ssc0_dmamask,
832 .coherent_dma_mask = DMA_BIT_MASK(32),
833 },
834 .resource = ssc0_resources,
835 .num_resources = ARRAY_SIZE(ssc0_resources),
836};
837
838static inline void configure_ssc0_pins(unsigned pins)
839{
840 if (pins & ATMEL_SSC_TF)
841 at91_set_A_periph(AT91_PIN_PD1, 1);
842 if (pins & ATMEL_SSC_TK)
843 at91_set_A_periph(AT91_PIN_PD0, 1);
844 if (pins & ATMEL_SSC_TD)
845 at91_set_A_periph(AT91_PIN_PD2, 1);
846 if (pins & ATMEL_SSC_RD)
847 at91_set_A_periph(AT91_PIN_PD3, 1);
848 if (pins & ATMEL_SSC_RK)
849 at91_set_A_periph(AT91_PIN_PD4, 1);
850 if (pins & ATMEL_SSC_RF)
851 at91_set_A_periph(AT91_PIN_PD5, 1);
852}
853
854static u64 ssc1_dmamask = DMA_BIT_MASK(32);
855
856static struct resource ssc1_resources[] = {
857 [0] = {
858 .start = AT91SAM9G45_BASE_SSC1,
859 .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
860 .flags = IORESOURCE_MEM,
861 },
862 [1] = {
863 .start = AT91SAM9G45_ID_SSC1,
864 .end = AT91SAM9G45_ID_SSC1,
865 .flags = IORESOURCE_IRQ,
866 },
867};
868
869static struct platform_device at91sam9g45_ssc1_device = {
870 .name = "ssc",
871 .id = 1,
872 .dev = {
873 .dma_mask = &ssc1_dmamask,
874 .coherent_dma_mask = DMA_BIT_MASK(32),
875 },
876 .resource = ssc1_resources,
877 .num_resources = ARRAY_SIZE(ssc1_resources),
878};
879
880static inline void configure_ssc1_pins(unsigned pins)
881{
882 if (pins & ATMEL_SSC_TF)
883 at91_set_A_periph(AT91_PIN_PD14, 1);
884 if (pins & ATMEL_SSC_TK)
885 at91_set_A_periph(AT91_PIN_PD12, 1);
886 if (pins & ATMEL_SSC_TD)
887 at91_set_A_periph(AT91_PIN_PD10, 1);
888 if (pins & ATMEL_SSC_RD)
889 at91_set_A_periph(AT91_PIN_PD11, 1);
890 if (pins & ATMEL_SSC_RK)
891 at91_set_A_periph(AT91_PIN_PD13, 1);
892 if (pins & ATMEL_SSC_RF)
893 at91_set_A_periph(AT91_PIN_PD15, 1);
894}
895
896/*
897 * SSC controllers are accessed through library code, instead of any
898 * kind of all-singing/all-dancing driver. For example one could be
899 * used by a particular I2S audio codec's driver, while another one
900 * on the same system might be used by a custom data capture driver.
901 */
902void __init at91_add_device_ssc(unsigned id, unsigned pins)
903{
904 struct platform_device *pdev;
905
906 /*
907 * NOTE: caller is responsible for passing information matching
908 * "pins" to whatever will be using each particular controller.
909 */
910 switch (id) {
911 case AT91SAM9G45_ID_SSC0:
912 pdev = &at91sam9g45_ssc0_device;
913 configure_ssc0_pins(pins);
914 at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
915 break;
916 case AT91SAM9G45_ID_SSC1:
917 pdev = &at91sam9g45_ssc1_device;
918 configure_ssc1_pins(pins);
919 at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
920 break;
921 default:
922 return;
923 }
924
925 platform_device_register(pdev);
926}
927
928#else
929void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
930#endif
931
932
933/* --------------------------------------------------------------------
934 * UART
935 * -------------------------------------------------------------------- */
936
937#if defined(CONFIG_SERIAL_ATMEL)
938static struct resource dbgu_resources[] = {
939 [0] = {
940 .start = AT91_VA_BASE_SYS + AT91_DBGU,
941 .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
942 .flags = IORESOURCE_MEM,
943 },
944 [1] = {
945 .start = AT91_ID_SYS,
946 .end = AT91_ID_SYS,
947 .flags = IORESOURCE_IRQ,
948 },
949};
950
951static struct atmel_uart_data dbgu_data = {
952 .use_dma_tx = 0,
953 .use_dma_rx = 0,
954 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
955};
956
957static u64 dbgu_dmamask = DMA_BIT_MASK(32);
958
959static struct platform_device at91sam9g45_dbgu_device = {
960 .name = "atmel_usart",
961 .id = 0,
962 .dev = {
963 .dma_mask = &dbgu_dmamask,
964 .coherent_dma_mask = DMA_BIT_MASK(32),
965 .platform_data = &dbgu_data,
966 },
967 .resource = dbgu_resources,
968 .num_resources = ARRAY_SIZE(dbgu_resources),
969};
970
971static inline void configure_dbgu_pins(void)
972{
973 at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */
974 at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */
975}
976
977static struct resource uart0_resources[] = {
978 [0] = {
979 .start = AT91SAM9G45_BASE_US0,
980 .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1,
981 .flags = IORESOURCE_MEM,
982 },
983 [1] = {
984 .start = AT91SAM9G45_ID_US0,
985 .end = AT91SAM9G45_ID_US0,
986 .flags = IORESOURCE_IRQ,
987 },
988};
989
990static struct atmel_uart_data uart0_data = {
991 .use_dma_tx = 1,
992 .use_dma_rx = 1,
993};
994
995static u64 uart0_dmamask = DMA_BIT_MASK(32);
996
997static struct platform_device at91sam9g45_uart0_device = {
998 .name = "atmel_usart",
999 .id = 1,
1000 .dev = {
1001 .dma_mask = &uart0_dmamask,
1002 .coherent_dma_mask = DMA_BIT_MASK(32),
1003 .platform_data = &uart0_data,
1004 },
1005 .resource = uart0_resources,
1006 .num_resources = ARRAY_SIZE(uart0_resources),
1007};
1008
1009static inline void configure_usart0_pins(unsigned pins)
1010{
1011 at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */
1012 at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */
1013
1014 if (pins & ATMEL_UART_RTS)
1015 at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */
1016 if (pins & ATMEL_UART_CTS)
1017 at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */
1018}
1019
1020static struct resource uart1_resources[] = {
1021 [0] = {
1022 .start = AT91SAM9G45_BASE_US1,
1023 .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1,
1024 .flags = IORESOURCE_MEM,
1025 },
1026 [1] = {
1027 .start = AT91SAM9G45_ID_US1,
1028 .end = AT91SAM9G45_ID_US1,
1029 .flags = IORESOURCE_IRQ,
1030 },
1031};
1032
1033static struct atmel_uart_data uart1_data = {
1034 .use_dma_tx = 1,
1035 .use_dma_rx = 1,
1036};
1037
1038static u64 uart1_dmamask = DMA_BIT_MASK(32);
1039
1040static struct platform_device at91sam9g45_uart1_device = {
1041 .name = "atmel_usart",
1042 .id = 2,
1043 .dev = {
1044 .dma_mask = &uart1_dmamask,
1045 .coherent_dma_mask = DMA_BIT_MASK(32),
1046 .platform_data = &uart1_data,
1047 },
1048 .resource = uart1_resources,
1049 .num_resources = ARRAY_SIZE(uart1_resources),
1050};
1051
1052static inline void configure_usart1_pins(unsigned pins)
1053{
1054 at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */
1055 at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */
1056
1057 if (pins & ATMEL_UART_RTS)
1058 at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */
1059 if (pins & ATMEL_UART_CTS)
1060 at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */
1061}
1062
1063static struct resource uart2_resources[] = {
1064 [0] = {
1065 .start = AT91SAM9G45_BASE_US2,
1066 .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1,
1067 .flags = IORESOURCE_MEM,
1068 },
1069 [1] = {
1070 .start = AT91SAM9G45_ID_US2,
1071 .end = AT91SAM9G45_ID_US2,
1072 .flags = IORESOURCE_IRQ,
1073 },
1074};
1075
1076static struct atmel_uart_data uart2_data = {
1077 .use_dma_tx = 1,
1078 .use_dma_rx = 1,
1079};
1080
1081static u64 uart2_dmamask = DMA_BIT_MASK(32);
1082
1083static struct platform_device at91sam9g45_uart2_device = {
1084 .name = "atmel_usart",
1085 .id = 3,
1086 .dev = {
1087 .dma_mask = &uart2_dmamask,
1088 .coherent_dma_mask = DMA_BIT_MASK(32),
1089 .platform_data = &uart2_data,
1090 },
1091 .resource = uart2_resources,
1092 .num_resources = ARRAY_SIZE(uart2_resources),
1093};
1094
1095static inline void configure_usart2_pins(unsigned pins)
1096{
1097 at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */
1098 at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */
1099
1100 if (pins & ATMEL_UART_RTS)
1101 at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */
1102 if (pins & ATMEL_UART_CTS)
1103 at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */
1104}
1105
1106static struct resource uart3_resources[] = {
1107 [0] = {
1108 .start = AT91SAM9G45_BASE_US3,
1109 .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1,
1110 .flags = IORESOURCE_MEM,
1111 },
1112 [1] = {
1113 .start = AT91SAM9G45_ID_US3,
1114 .end = AT91SAM9G45_ID_US3,
1115 .flags = IORESOURCE_IRQ,
1116 },
1117};
1118
1119static struct atmel_uart_data uart3_data = {
1120 .use_dma_tx = 1,
1121 .use_dma_rx = 1,
1122};
1123
1124static u64 uart3_dmamask = DMA_BIT_MASK(32);
1125
1126static struct platform_device at91sam9g45_uart3_device = {
1127 .name = "atmel_usart",
1128 .id = 4,
1129 .dev = {
1130 .dma_mask = &uart3_dmamask,
1131 .coherent_dma_mask = DMA_BIT_MASK(32),
1132 .platform_data = &uart3_data,
1133 },
1134 .resource = uart3_resources,
1135 .num_resources = ARRAY_SIZE(uart3_resources),
1136};
1137
1138static inline void configure_usart3_pins(unsigned pins)
1139{
1140 at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */
1141 at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */
1142
1143 if (pins & ATMEL_UART_RTS)
1144 at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */
1145 if (pins & ATMEL_UART_CTS)
1146 at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */
1147}
1148
1149static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
1150struct platform_device *atmel_default_console_device; /* the serial console device */
1151
1152void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
1153{
1154 struct platform_device *pdev;
1155
1156 switch (id) {
1157 case 0: /* DBGU */
1158 pdev = &at91sam9g45_dbgu_device;
1159 configure_dbgu_pins();
1160 at91_clock_associate("mck", &pdev->dev, "usart");
1161 break;
1162 case AT91SAM9G45_ID_US0:
1163 pdev = &at91sam9g45_uart0_device;
1164 configure_usart0_pins(pins);
1165 at91_clock_associate("usart0_clk", &pdev->dev, "usart");
1166 break;
1167 case AT91SAM9G45_ID_US1:
1168 pdev = &at91sam9g45_uart1_device;
1169 configure_usart1_pins(pins);
1170 at91_clock_associate("usart1_clk", &pdev->dev, "usart");
1171 break;
1172 case AT91SAM9G45_ID_US2:
1173 pdev = &at91sam9g45_uart2_device;
1174 configure_usart2_pins(pins);
1175 at91_clock_associate("usart2_clk", &pdev->dev, "usart");
1176 break;
1177 case AT91SAM9G45_ID_US3:
1178 pdev = &at91sam9g45_uart3_device;
1179 configure_usart3_pins(pins);
1180 at91_clock_associate("usart3_clk", &pdev->dev, "usart");
1181 break;
1182 default:
1183 return;
1184 }
1185 pdev->id = portnr; /* update to mapped ID */
1186
1187 if (portnr < ATMEL_MAX_UART)
1188 at91_uarts[portnr] = pdev;
1189}
1190
1191void __init at91_set_serial_console(unsigned portnr)
1192{
1193 if (portnr < ATMEL_MAX_UART)
1194 atmel_default_console_device = at91_uarts[portnr];
1195}
1196
1197void __init at91_add_device_serial(void)
1198{
1199 int i;
1200
1201 for (i = 0; i < ATMEL_MAX_UART; i++) {
1202 if (at91_uarts[i])
1203 platform_device_register(at91_uarts[i]);
1204 }
1205
1206 if (!atmel_default_console_device)
1207 printk(KERN_INFO "AT91: No default serial console defined.\n");
1208}
1209#else
1210void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
1211void __init at91_set_serial_console(unsigned portnr) {}
1212void __init at91_add_device_serial(void) {}
1213#endif
1214
1215
1216/* -------------------------------------------------------------------- */
1217/*
1218 * These devices are always present and don't need any board-specific
1219 * setup.
1220 */
1221static int __init at91_add_standard_devices(void)
1222{
1223 at91_add_device_rtc();
1224 at91_add_device_rtt();
1225 at91_add_device_watchdog();
1226 at91_add_device_tc();
1227 return 0;
1228}
1229
1230arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 970fd6b6753e..61e52b66bc72 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -174,6 +174,16 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
174 }, 174 },
175}; 175};
176 176
177/*
178 * IDE (CF True IDE mode)
179 */
180static struct at91_cf_data afeb9260_cf_data = {
181 .chipselect = 4,
182 .irq_pin = AT91_PIN_PA6,
183 .rst_pin = AT91_PIN_PA7,
184 .flags = AT91_CF_TRUE_IDE,
185};
186
177static void __init afeb9260_board_init(void) 187static void __init afeb9260_board_init(void)
178{ 188{
179 /* Serial */ 189 /* Serial */
@@ -202,6 +212,8 @@ static void __init afeb9260_board_init(void)
202 ARRAY_SIZE(afeb9260_i2c_devices)); 212 ARRAY_SIZE(afeb9260_i2c_devices));
203 /* Audio */ 213 /* Audio */
204 at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); 214 at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
215 /* IDE */
216 at91_add_device_cf(&afeb9260_cf_data);
205} 217}
206 218
207MACHINE_START(AFEB9260, "Custom afeb9260 board") 219MACHINE_START(AFEB9260, "Custom afeb9260 board")
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
new file mode 100644
index 000000000000..4bc2e9f6ebb5
--- /dev/null
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -0,0 +1,385 @@
1/*
2 * linux/arch/arm/mach-at91/board-cpu9krea.c
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2006 Atmel
6 * Copyright (C) 2009 Eric Benard - eric@eukrea.com
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/types.h>
24#include <linux/init.h>
25#include <linux/mm.h>
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/clk.h>
29#include <linux/gpio_keys.h>
30#include <linux/input.h>
31#include <linux/mtd/physmap.h>
32
33#include <asm/setup.h>
34#include <asm/mach-types.h>
35#include <asm/irq.h>
36
37#include <asm/mach/arch.h>
38#include <asm/mach/map.h>
39#include <asm/mach/irq.h>
40
41#include <mach/hardware.h>
42#include <mach/board.h>
43#include <mach/gpio.h>
44#include <mach/at91sam9_smc.h>
45#include <mach/at91sam9260_matrix.h>
46
47#include "sam9_smc.h"
48#include "generic.h"
49
50static void __init cpu9krea_map_io(void)
51{
52 /* Initialize processor: 18.432 MHz crystal */
53 at91sam9260_initialize(18432000);
54
55 /* DGBU on ttyS0. (Rx & Tx only) */
56 at91_register_uart(0, 0, 0);
57
58 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
59 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
60 ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
61 ATMEL_UART_DCD | ATMEL_UART_RI);
62
63 /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
64 at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS |
65 ATMEL_UART_RTS);
66
67 /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */
68 at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS |
69 ATMEL_UART_RTS);
70
71 /* USART3 on ttyS4. (Rx, Tx) */
72 at91_register_uart(AT91SAM9260_ID_US3, 4, 0);
73
74 /* USART4 on ttyS5. (Rx, Tx) */
75 at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
76
77 /* USART5 on ttyS6. (Rx, Tx) */
78 at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
79
80 /* set serial console to ttyS0 (ie, DBGU) */
81 at91_set_serial_console(0);
82}
83
84static void __init cpu9krea_init_irq(void)
85{
86 at91sam9260_init_interrupts(NULL);
87}
88
89/*
90 * USB Host port
91 */
92static struct at91_usbh_data __initdata cpu9krea_usbh_data = {
93 .ports = 2,
94};
95
96/*
97 * USB Device port
98 */
99static struct at91_udc_data __initdata cpu9krea_udc_data = {
100 .vbus_pin = AT91_PIN_PC8,
101 .pullup_pin = 0, /* pull-up driven by UDC */
102};
103
104/*
105 * MACB Ethernet device
106 */
107static struct at91_eth_data __initdata cpu9krea_macb_data = {
108 .is_rmii = 1,
109};
110
111/*
112 * NAND flash
113 */
114static struct atmel_nand_data __initdata cpu9krea_nand_data = {
115 .ale = 21,
116 .cle = 22,
117 .rdy_pin = AT91_PIN_PC13,
118 .enable_pin = AT91_PIN_PC14,
119 .bus_width_16 = 0,
120};
121
122#ifdef CONFIG_MACH_CPU9260
123static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
124 .ncs_read_setup = 0,
125 .nrd_setup = 1,
126 .ncs_write_setup = 0,
127 .nwe_setup = 1,
128
129 .ncs_read_pulse = 3,
130 .nrd_pulse = 3,
131 .ncs_write_pulse = 3,
132 .nwe_pulse = 3,
133
134 .read_cycle = 5,
135 .write_cycle = 5,
136
137 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
138 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
139 .tdf_cycles = 2,
140};
141#else
142static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
143 .ncs_read_setup = 0,
144 .nrd_setup = 2,
145 .ncs_write_setup = 0,
146 .nwe_setup = 2,
147
148 .ncs_read_pulse = 4,
149 .nrd_pulse = 4,
150 .ncs_write_pulse = 4,
151 .nwe_pulse = 4,
152
153 .read_cycle = 7,
154 .write_cycle = 7,
155
156 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
157 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
158 .tdf_cycles = 3,
159};
160#endif
161
162static void __init cpu9krea_add_device_nand(void)
163{
164 sam9_smc_configure(3, &cpu9krea_nand_smc_config);
165 at91_add_device_nand(&cpu9krea_nand_data);
166}
167
168/*
169 * NOR flash
170 */
171static struct physmap_flash_data cpuat9260_nor_data = {
172 .width = 2,
173};
174
175#define NOR_BASE AT91_CHIPSELECT_0
176#define NOR_SIZE SZ_64M
177
178static struct resource nor_flash_resources[] = {
179 {
180 .start = NOR_BASE,
181 .end = NOR_BASE + NOR_SIZE - 1,
182 .flags = IORESOURCE_MEM,
183 }
184};
185
186static struct platform_device cpu9krea_nor_flash = {
187 .name = "physmap-flash",
188 .id = 0,
189 .dev = {
190 .platform_data = &cpuat9260_nor_data,
191 },
192 .resource = nor_flash_resources,
193 .num_resources = ARRAY_SIZE(nor_flash_resources),
194};
195
196#ifdef CONFIG_MACH_CPU9260
197static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
198 .ncs_read_setup = 0,
199 .nrd_setup = 1,
200 .ncs_write_setup = 0,
201 .nwe_setup = 1,
202
203 .ncs_read_pulse = 10,
204 .nrd_pulse = 10,
205 .ncs_write_pulse = 6,
206 .nwe_pulse = 6,
207
208 .read_cycle = 12,
209 .write_cycle = 8,
210
211 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
212 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
213 | AT91_SMC_DBW_16,
214 .tdf_cycles = 2,
215};
216#else
217static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
218 .ncs_read_setup = 0,
219 .nrd_setup = 1,
220 .ncs_write_setup = 0,
221 .nwe_setup = 1,
222
223 .ncs_read_pulse = 13,
224 .nrd_pulse = 13,
225 .ncs_write_pulse = 8,
226 .nwe_pulse = 8,
227
228 .read_cycle = 15,
229 .write_cycle = 10,
230
231 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
232 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
233 | AT91_SMC_DBW_16,
234 .tdf_cycles = 2,
235};
236#endif
237
238static __init void cpu9krea_add_device_nor(void)
239{
240 unsigned long csa;
241
242 csa = at91_sys_read(AT91_MATRIX_EBICSA);
243 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
244
245 /* configure chip-select 0 (NOR) */
246 sam9_smc_configure(0, &cpu9krea_nor_smc_config);
247
248 platform_device_register(&cpu9krea_nor_flash);
249}
250
251/*
252 * LEDs
253 */
254static struct gpio_led cpu9krea_leds[] = {
255 { /* LED1 */
256 .name = "LED1",
257 .gpio = AT91_PIN_PC11,
258 .active_low = 1,
259 .default_trigger = "timer",
260 },
261 { /* LED2 */
262 .name = "LED2",
263 .gpio = AT91_PIN_PC12,
264 .active_low = 1,
265 .default_trigger = "heartbeat",
266 },
267 { /* LED3 */
268 .name = "LED3",
269 .gpio = AT91_PIN_PC7,
270 .active_low = 1,
271 .default_trigger = "none",
272 },
273 { /* LED4 */
274 .name = "LED4",
275 .gpio = AT91_PIN_PC9,
276 .active_low = 1,
277 .default_trigger = "none",
278 }
279};
280
281static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = {
282 {
283 I2C_BOARD_INFO("rtc-ds1307", 0x68),
284 .type = "ds1339",
285 },
286};
287
288/*
289 * GPIO Buttons
290 */
291#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
292static struct gpio_keys_button cpu9krea_buttons[] = {
293 {
294 .gpio = AT91_PIN_PC3,
295 .code = BTN_0,
296 .desc = "BP1",
297 .active_low = 1,
298 .wakeup = 1,
299 },
300 {
301 .gpio = AT91_PIN_PB20,
302 .code = BTN_1,
303 .desc = "BP2",
304 .active_low = 1,
305 .wakeup = 1,
306 }
307};
308
309static struct gpio_keys_platform_data cpu9krea_button_data = {
310 .buttons = cpu9krea_buttons,
311 .nbuttons = ARRAY_SIZE(cpu9krea_buttons),
312};
313
314static struct platform_device cpu9krea_button_device = {
315 .name = "gpio-keys",
316 .id = -1,
317 .num_resources = 0,
318 .dev = {
319 .platform_data = &cpu9krea_button_data,
320 }
321};
322
323static void __init cpu9krea_add_device_buttons(void)
324{
325 at91_set_gpio_input(AT91_PIN_PC3, 1); /* BP1 */
326 at91_set_deglitch(AT91_PIN_PC3, 1);
327 at91_set_gpio_input(AT91_PIN_PB20, 1); /* BP2 */
328 at91_set_deglitch(AT91_PIN_PB20, 1);
329
330 platform_device_register(&cpu9krea_button_device);
331}
332#else
333static void __init cpu9krea_add_device_buttons(void)
334{
335}
336#endif
337
338/*
339 * MCI (SD/MMC)
340 */
341static struct at91_mmc_data __initdata cpu9krea_mmc_data = {
342 .slot_b = 0,
343 .wire4 = 1,
344 .det_pin = AT91_PIN_PA29,
345};
346
347static void __init cpu9krea_board_init(void)
348{
349 /* NOR */
350 cpu9krea_add_device_nor();
351 /* Serial */
352 at91_add_device_serial();
353 /* USB Host */
354 at91_add_device_usbh(&cpu9krea_usbh_data);
355 /* USB Device */
356 at91_add_device_udc(&cpu9krea_udc_data);
357 /* NAND */
358 cpu9krea_add_device_nand();
359 /* Ethernet */
360 at91_add_device_eth(&cpu9krea_macb_data);
361 /* MMC */
362 at91_add_device_mmc(0, &cpu9krea_mmc_data);
363 /* I2C */
364 at91_add_device_i2c(cpu9krea_i2c_devices,
365 ARRAY_SIZE(cpu9krea_i2c_devices));
366 /* LEDs */
367 at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds));
368 /* Push Buttons */
369 cpu9krea_add_device_buttons();
370}
371
372#ifdef CONFIG_MACH_CPU9260
373MACHINE_START(CPUAT9260, "Eukrea CPU9260")
374#else
375MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
376#endif
377 /* Maintainer: Eric Benard - EUKREA Electromatique */
378 .phys_io = AT91_BASE_SYS,
379 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
380 .boot_params = AT91_SDRAM_BASE + 0x100,
381 .timer = &at91sam926x_timer,
382 .map_io = cpu9krea_map_io,
383 .init_irq = cpu9krea_init_irq,
384 .init_machine = cpu9krea_board_init,
385MACHINE_END
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c
new file mode 100644
index 000000000000..a28d99656190
--- /dev/null
+++ b/arch/arm/mach-at91/board-cpuat91.c
@@ -0,0 +1,185 @@
1/*
2 * linux/arch/arm/mach-at91/board-cpuat91.c
3 *
4 * Copyright (C) 2009 Eric Benard - eric@eukrea.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/types.h>
22#include <linux/init.h>
23#include <linux/mm.h>
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/mtd/physmap.h>
27#include <linux/mtd/plat-ram.h>
28
29#include <mach/hardware.h>
30#include <asm/setup.h>
31#include <asm/mach-types.h>
32#include <asm/irq.h>
33
34#include <asm/mach/arch.h>
35#include <asm/mach/map.h>
36#include <asm/mach/irq.h>
37
38#include <mach/board.h>
39#include <mach/gpio.h>
40#include <mach/at91rm9200_mc.h>
41
42#include "generic.h"
43
44static struct gpio_led cpuat91_leds[] = {
45 {
46 .name = "led1",
47 .default_trigger = "heartbeat",
48 .active_low = 1,
49 .gpio = AT91_PIN_PC0,
50 },
51};
52
53static void __init cpuat91_map_io(void)
54{
55 /* Initialize processor: 18.432 MHz crystal */
56 at91rm9200_initialize(18432000, AT91RM9200_PQFP);
57
58 /* DBGU on ttyS0. (Rx & Tx only) */
59 at91_register_uart(0, 0, 0);
60
61 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */
62 at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS |
63 ATMEL_UART_RTS);
64
65 /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
66 at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS |
67 ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
68 ATMEL_UART_DCD | ATMEL_UART_RI);
69
70 /* USART2 on ttyS3 (Rx, Tx) */
71 at91_register_uart(AT91RM9200_ID_US2, 3, 0);
72
73 /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */
74 at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS |
75 ATMEL_UART_RTS);
76
77 /* set serial console to ttyS0 (ie, DBGU) */
78 at91_set_serial_console(0);
79}
80
81static void __init cpuat91_init_irq(void)
82{
83 at91rm9200_init_interrupts(NULL);
84}
85
86static struct at91_eth_data __initdata cpuat91_eth_data = {
87 .is_rmii = 1,
88};
89
90static struct at91_usbh_data __initdata cpuat91_usbh_data = {
91 .ports = 1,
92};
93
94static struct at91_udc_data __initdata cpuat91_udc_data = {
95 .vbus_pin = AT91_PIN_PC15,
96 .pullup_pin = AT91_PIN_PC14,
97};
98
99static struct at91_mmc_data __initdata cpuat91_mmc_data = {
100 .det_pin = AT91_PIN_PC2,
101 .wire4 = 1,
102};
103
104static struct physmap_flash_data cpuat91_flash_data = {
105 .width = 2,
106};
107
108static struct resource cpuat91_flash_resource = {
109 .start = AT91_CHIPSELECT_0,
110 .end = AT91_CHIPSELECT_0 + SZ_16M - 1,
111 .flags = IORESOURCE_MEM,
112};
113
114static struct platform_device cpuat91_norflash = {
115 .name = "physmap-flash",
116 .id = 0,
117 .dev = {
118 .platform_data = &cpuat91_flash_data,
119 },
120 .resource = &cpuat91_flash_resource,
121 .num_resources = 1,
122};
123
124#ifdef CONFIG_MTD_PLATRAM
125struct platdata_mtd_ram at91_sram_pdata = {
126 .mapname = "SRAM",
127 .bankwidth = 2,
128};
129
130static struct resource at91_sram_resource[] = {
131 [0] = {
132 .start = AT91RM9200_SRAM_BASE,
133 .end = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1,
134 .flags = IORESOURCE_MEM,
135 },
136};
137
138static struct platform_device at91_sram = {
139 .name = "mtd-ram",
140 .id = 0,
141 .resource = at91_sram_resource,
142 .num_resources = ARRAY_SIZE(at91_sram_resource),
143 .dev = {
144 .platform_data = &at91_sram_pdata,
145 },
146};
147#endif /* MTD_PLATRAM */
148
149static struct platform_device *platform_devices[] __initdata = {
150 &cpuat91_norflash,
151#ifdef CONFIG_MTD_PLATRAM
152 &at91_sram,
153#endif /* CONFIG_MTD_PLATRAM */
154};
155
156static void __init cpuat91_board_init(void)
157{
158 /* Serial */
159 at91_add_device_serial();
160 /* LEDs. */
161 at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds));
162 /* Ethernet */
163 at91_add_device_eth(&cpuat91_eth_data);
164 /* USB Host */
165 at91_add_device_usbh(&cpuat91_usbh_data);
166 /* USB Device */
167 at91_add_device_udc(&cpuat91_udc_data);
168 /* MMC */
169 at91_add_device_mmc(0, &cpuat91_mmc_data);
170 /* I2C */
171 at91_add_device_i2c(NULL, 0);
172 /* Platform devices */
173 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
174}
175
176MACHINE_START(CPUAT91, "Eukrea")
177 /* Maintainer: Eric Benard - EUKREA Electromatique */
178 .phys_io = AT91_BASE_SYS,
179 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
180 .boot_params = AT91_SDRAM_BASE + 0x100,
181 .timer = &at91rm9200_timer,
182 .map_io = cpuat91_map_io,
183 .init_irq = cpuat91_init_irq,
184 .init_machine = cpuat91_board_init,
185MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index d5266da55311..f9b19993a7a9 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -287,7 +287,11 @@ static void __init ek_add_device_ts(void) {}
287 */ 287 */
288static struct at73c213_board_info at73c213_data = { 288static struct at73c213_board_info at73c213_data = {
289 .ssc_id = 1, 289 .ssc_id = 1,
290#if defined(CONFIG_MACH_AT91SAM9261EK)
290 .shortname = "AT91SAM9261-EK external DAC", 291 .shortname = "AT91SAM9261-EK external DAC",
292#else
293 .shortname = "AT91SAM9G10-EK external DAC",
294#endif
291}; 295};
292 296
293#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) 297#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
@@ -414,6 +418,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
414 .default_monspecs = &at91fb_default_stn_monspecs, 418 .default_monspecs = &at91fb_default_stn_monspecs,
415 .atmel_lcdfb_power_control = at91_lcdc_stn_power_control, 419 .atmel_lcdfb_power_control = at91_lcdc_stn_power_control,
416 .guard_time = 1, 420 .guard_time = 1,
421#if defined(CONFIG_MACH_AT91SAM9G10EK)
422 .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
423#endif
417}; 424};
418 425
419#else 426#else
@@ -467,6 +474,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
467 .default_monspecs = &at91fb_default_tft_monspecs, 474 .default_monspecs = &at91fb_default_tft_monspecs,
468 .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, 475 .atmel_lcdfb_power_control = at91_lcdc_tft_power_control,
469 .guard_time = 1, 476 .guard_time = 1,
477#if defined(CONFIG_MACH_AT91SAM9G10EK)
478 .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
479#endif
470}; 480};
471#endif 481#endif
472 482
@@ -600,7 +610,11 @@ static void __init ek_board_init(void)
600 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); 610 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
601} 611}
602 612
613#if defined(CONFIG_MACH_AT91SAM9261EK)
603MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") 614MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
615#else
616MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
617#endif
604 /* Maintainer: Atmel */ 618 /* Maintainer: Atmel */
605 .phys_io = AT91_BASE_SYS, 619 .phys_io = AT91_BASE_SYS,
606 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, 620 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 57d52528f224..1bf7bd4cbe13 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -364,9 +364,9 @@ static void __init ek_add_device_buttons(void) {}
364 364
365/* 365/*
366 * AC97 366 * AC97
367 * reset_pin is not connected: NRST
367 */ 368 */
368static struct atmel_ac97_data ek_ac97_data = { 369static struct ac97c_platform_data ek_ac97_data = {
369 .reset_pin = AT91_PIN_PA13,
370}; 370};
371 371
372 372
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index a55398ed1211..ca470d504ea0 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -273,6 +273,7 @@ static void __init ek_add_device_buttons(void) {}
273static struct i2c_board_info __initdata ek_i2c_devices[] = { 273static struct i2c_board_info __initdata ek_i2c_devices[] = {
274 { 274 {
275 I2C_BOARD_INFO("24c512", 0x50), 275 I2C_BOARD_INFO("24c512", 0x50),
276 I2C_BOARD_INFO("wm8731", 0x1b),
276 }, 277 },
277}; 278};
278 279
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
new file mode 100644
index 000000000000..b8558eae5229
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -0,0 +1,389 @@
1/*
2 * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
3 *
4 * Covers: * AT91SAM9G45-EKES board
5 * * AT91SAM9M10G45-EK board
6 *
7 * Copyright (C) 2009 Atmel Corporation.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/spi/spi.h>
22#include <linux/fb.h>
23#include <linux/gpio_keys.h>
24#include <linux/input.h>
25#include <linux/leds.h>
26#include <linux/clk.h>
27
28#include <mach/hardware.h>
29#include <video/atmel_lcdc.h>
30
31#include <asm/setup.h>
32#include <asm/mach-types.h>
33#include <asm/irq.h>
34
35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach/irq.h>
38
39#include <mach/hardware.h>
40#include <mach/board.h>
41#include <mach/gpio.h>
42#include <mach/at91sam9_smc.h>
43#include <mach/at91_shdwc.h>
44
45#include "sam9_smc.h"
46#include "generic.h"
47
48
49static void __init ek_map_io(void)
50{
51 /* Initialize processor: 12.000 MHz crystal */
52 at91sam9g45_initialize(12000000);
53
54 /* DGBU on ttyS0. (Rx & Tx only) */
55 at91_register_uart(0, 0, 0);
56
57 /* USART0 not connected on the -EK board */
58 /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
59 at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
60
61 /* set serial console to ttyS0 (ie, DBGU) */
62 at91_set_serial_console(0);
63}
64
65static void __init ek_init_irq(void)
66{
67 at91sam9g45_init_interrupts(NULL);
68}
69
70
71/*
72 * USB HS Host port (common to OHCI & EHCI)
73 */
74static struct at91_usbh_data __initdata ek_usbh_hs_data = {
75 .ports = 2,
76 .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3},
77};
78
79
80/*
81 * USB HS Device port
82 */
83static struct usba_platform_data __initdata ek_usba_udc_data = {
84 .vbus_pin = AT91_PIN_PB19,
85};
86
87
88/*
89 * SPI devices.
90 */
91static struct spi_board_info ek_spi_devices[] = {
92 { /* DataFlash chip */
93 .modalias = "mtd_dataflash",
94 .chip_select = 0,
95 .max_speed_hz = 15 * 1000 * 1000,
96 .bus_num = 0,
97 },
98};
99
100
101/*
102 * MACB Ethernet device
103 */
104static struct at91_eth_data __initdata ek_macb_data = {
105 .phy_irq_pin = AT91_PIN_PD5,
106 .is_rmii = 1,
107};
108
109
110/*
111 * NAND flash
112 */
113static struct mtd_partition __initdata ek_nand_partition[] = {
114 {
115 .name = "Partition 1",
116 .offset = 0,
117 .size = SZ_64M,
118 },
119 {
120 .name = "Partition 2",
121 .offset = MTDPART_OFS_NXTBLK,
122 .size = MTDPART_SIZ_FULL,
123 },
124};
125
126static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
127{
128 *num_partitions = ARRAY_SIZE(ek_nand_partition);
129 return ek_nand_partition;
130}
131
132/* det_pin is not connected */
133static struct atmel_nand_data __initdata ek_nand_data = {
134 .ale = 21,
135 .cle = 22,
136 .rdy_pin = AT91_PIN_PC8,
137 .enable_pin = AT91_PIN_PC14,
138 .partition_info = nand_partitions,
139#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
140 .bus_width_16 = 1,
141#else
142 .bus_width_16 = 0,
143#endif
144};
145
146static struct sam9_smc_config __initdata ek_nand_smc_config = {
147 .ncs_read_setup = 0,
148 .nrd_setup = 2,
149 .ncs_write_setup = 0,
150 .nwe_setup = 2,
151
152 .ncs_read_pulse = 4,
153 .nrd_pulse = 4,
154 .ncs_write_pulse = 4,
155 .nwe_pulse = 4,
156
157 .read_cycle = 7,
158 .write_cycle = 7,
159
160 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
161 .tdf_cycles = 3,
162};
163
164static void __init ek_add_device_nand(void)
165{
166 /* setup bus-width (8 or 16) */
167 if (ek_nand_data.bus_width_16)
168 ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
169 else
170 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
171
172 /* configure chip-select 3 (NAND) */
173 sam9_smc_configure(3, &ek_nand_smc_config);
174
175 at91_add_device_nand(&ek_nand_data);
176}
177
178
179/*
180 * LCD Controller
181 */
182#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
183static struct fb_videomode at91_tft_vga_modes[] = {
184 {
185 .name = "LG",
186 .refresh = 60,
187 .xres = 480, .yres = 272,
188 .pixclock = KHZ2PICOS(9000),
189
190 .left_margin = 1, .right_margin = 1,
191 .upper_margin = 40, .lower_margin = 1,
192 .hsync_len = 45, .vsync_len = 1,
193
194 .sync = 0,
195 .vmode = FB_VMODE_NONINTERLACED,
196 },
197};
198
199static struct fb_monspecs at91fb_default_monspecs = {
200 .manufacturer = "LG",
201 .monitor = "LB043WQ1",
202
203 .modedb = at91_tft_vga_modes,
204 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
205 .hfmin = 15000,
206 .hfmax = 17640,
207 .vfmin = 57,
208 .vfmax = 67,
209};
210
211#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
212 | ATMEL_LCDC_DISTYPE_TFT \
213 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
214
215/* Driver datas */
216static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
217 .lcdcon_is_backlight = true,
218 .default_bpp = 32,
219 .default_dmacon = ATMEL_LCDC_DMAEN,
220 .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
221 .default_monspecs = &at91fb_default_monspecs,
222 .guard_time = 9,
223 .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
224};
225
226#else
227static struct atmel_lcdfb_info __initdata ek_lcdc_data;
228#endif
229
230
231/*
232 * GPIO Buttons
233 */
234#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
235static struct gpio_keys_button ek_buttons[] = {
236 { /* BP1, "leftclic" */
237 .code = BTN_LEFT,
238 .gpio = AT91_PIN_PB6,
239 .active_low = 1,
240 .desc = "left_click",
241 .wakeup = 1,
242 },
243 { /* BP2, "rightclic" */
244 .code = BTN_RIGHT,
245 .gpio = AT91_PIN_PB7,
246 .active_low = 1,
247 .desc = "right_click",
248 .wakeup = 1,
249 },
250 /* BP3, "joystick" */
251 {
252 .code = KEY_LEFT,
253 .gpio = AT91_PIN_PB14,
254 .active_low = 1,
255 .desc = "Joystick Left",
256 },
257 {
258 .code = KEY_RIGHT,
259 .gpio = AT91_PIN_PB15,
260 .active_low = 1,
261 .desc = "Joystick Right",
262 },
263 {
264 .code = KEY_UP,
265 .gpio = AT91_PIN_PB16,
266 .active_low = 1,
267 .desc = "Joystick Up",
268 },
269 {
270 .code = KEY_DOWN,
271 .gpio = AT91_PIN_PB17,
272 .active_low = 1,
273 .desc = "Joystick Down",
274 },
275 {
276 .code = KEY_ENTER,
277 .gpio = AT91_PIN_PB18,
278 .active_low = 1,
279 .desc = "Joystick Press",
280 },
281};
282
283static struct gpio_keys_platform_data ek_button_data = {
284 .buttons = ek_buttons,
285 .nbuttons = ARRAY_SIZE(ek_buttons),
286};
287
288static struct platform_device ek_button_device = {
289 .name = "gpio-keys",
290 .id = -1,
291 .num_resources = 0,
292 .dev = {
293 .platform_data = &ek_button_data,
294 }
295};
296
297static void __init ek_add_device_buttons(void)
298{
299 int i;
300
301 for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) {
302 at91_set_GPIO_periph(ek_buttons[i].gpio, 1);
303 at91_set_deglitch(ek_buttons[i].gpio, 1);
304 }
305
306 platform_device_register(&ek_button_device);
307}
308#else
309static void __init ek_add_device_buttons(void) {}
310#endif
311
312
313/*
314 * LEDs ... these could all be PWM-driven, for variable brightness
315 */
316static struct gpio_led ek_leds[] = {
317 { /* "top" led, red, powerled */
318 .name = "d8",
319 .gpio = AT91_PIN_PD30,
320 .default_trigger = "heartbeat",
321 },
322 { /* "left" led, green, userled2, pwm3 */
323 .name = "d6",
324 .gpio = AT91_PIN_PD0,
325 .active_low = 1,
326 .default_trigger = "nand-disk",
327 },
328#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE))
329 { /* "right" led, green, userled1, pwm1 */
330 .name = "d7",
331 .gpio = AT91_PIN_PD31,
332 .active_low = 1,
333 .default_trigger = "mmc0",
334 },
335#endif
336};
337
338
339/*
340 * PWM Leds
341 */
342static struct gpio_led ek_pwm_led[] = {
343#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)
344 { /* "right" led, green, userled1, pwm1 */
345 .name = "d7",
346 .gpio = 1, /* is PWM channel number */
347 .active_low = 1,
348 .default_trigger = "none",
349 },
350#endif
351};
352
353
354
355static void __init ek_board_init(void)
356{
357 /* Serial */
358 at91_add_device_serial();
359 /* USB HS Host */
360 at91_add_device_usbh_ohci(&ek_usbh_hs_data);
361 /* USB HS Device */
362 at91_add_device_usba(&ek_usba_udc_data);
363 /* SPI */
364 at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
365 /* Ethernet */
366 at91_add_device_eth(&ek_macb_data);
367 /* NAND */
368 ek_add_device_nand();
369 /* I2C */
370 at91_add_device_i2c(0, NULL, 0);
371 /* LCD Controller */
372 at91_add_device_lcdc(&ek_lcdc_data);
373 /* Push Buttons */
374 ek_add_device_buttons();
375 /* LEDs */
376 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
377 at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
378}
379
380MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
381 /* Maintainer: Atmel */
382 .phys_io = AT91_BASE_SYS,
383 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
384 .boot_params = AT91_SDRAM_BASE + 0x100,
385 .timer = &at91sam926x_timer,
386 .map_io = ek_map_io,
387 .init_irq = ek_init_irq,
388 .init_machine = ek_board_init,
389MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index f6b5672cabd6..9d07679efce7 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -15,6 +15,8 @@
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <linux/fb.h> 16#include <linux/fb.h>
17#include <linux/clk.h> 17#include <linux/clk.h>
18#include <linux/input.h>
19#include <linux/gpio_keys.h>
18 20
19#include <video/atmel_lcdc.h> 21#include <video/atmel_lcdc.h>
20 22
@@ -208,6 +210,79 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
208#endif 210#endif
209 211
210 212
213/*
214 * LEDs
215 */
216static struct gpio_led ek_leds[] = {
217 { /* "bottom" led, green, userled1 to be defined */
218 .name = "ds1",
219 .gpio = AT91_PIN_PD15,
220 .active_low = 1,
221 .default_trigger = "none",
222 },
223 { /* "bottom" led, green, userled2 to be defined */
224 .name = "ds2",
225 .gpio = AT91_PIN_PD16,
226 .active_low = 1,
227 .default_trigger = "none",
228 },
229 { /* "power" led, yellow */
230 .name = "ds3",
231 .gpio = AT91_PIN_PD14,
232 .default_trigger = "heartbeat",
233 }
234};
235
236
237/*
238 * GPIO Buttons
239 */
240#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
241static struct gpio_keys_button ek_buttons[] = {
242 {
243 .gpio = AT91_PIN_PB0,
244 .code = BTN_2,
245 .desc = "Right Click",
246 .active_low = 1,
247 .wakeup = 1,
248 },
249 {
250 .gpio = AT91_PIN_PB1,
251 .code = BTN_1,
252 .desc = "Left Click",
253 .active_low = 1,
254 .wakeup = 1,
255 }
256};
257
258static struct gpio_keys_platform_data ek_button_data = {
259 .buttons = ek_buttons,
260 .nbuttons = ARRAY_SIZE(ek_buttons),
261};
262
263static struct platform_device ek_button_device = {
264 .name = "gpio-keys",
265 .id = -1,
266 .num_resources = 0,
267 .dev = {
268 .platform_data = &ek_button_data,
269 }
270};
271
272static void __init ek_add_device_buttons(void)
273{
274 at91_set_gpio_input(AT91_PIN_PB1, 1); /* btn1 */
275 at91_set_deglitch(AT91_PIN_PB1, 1);
276 at91_set_gpio_input(AT91_PIN_PB0, 1); /* btn2 */
277 at91_set_deglitch(AT91_PIN_PB0, 1);
278
279 platform_device_register(&ek_button_device);
280}
281#else
282static void __init ek_add_device_buttons(void) {}
283#endif
284
285
211static void __init ek_board_init(void) 286static void __init ek_board_init(void)
212{ 287{
213 /* Serial */ 288 /* Serial */
@@ -226,6 +301,10 @@ static void __init ek_board_init(void)
226 at91_add_device_lcdc(&ek_lcdc_data); 301 at91_add_device_lcdc(&ek_lcdc_data);
227 /* Touch Screen Controller */ 302 /* Touch Screen Controller */
228 at91_add_device_tsadcc(); 303 at91_add_device_tsadcc();
304 /* LEDs */
305 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
306 /* Push Buttons */
307 ek_add_device_buttons();
229} 308}
230 309
231MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") 310MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index bac578fe0d3d..c042dcf4725f 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -47,20 +47,25 @@
47 * Chips have some kind of clocks : group them by functionality 47 * Chips have some kind of clocks : group them by functionality
48 */ 48 */
49#define cpu_has_utmi() ( cpu_is_at91cap9() \ 49#define cpu_has_utmi() ( cpu_is_at91cap9() \
50 || cpu_is_at91sam9rl()) 50 || cpu_is_at91sam9rl() \
51 || cpu_is_at91sam9g45())
51 52
52#define cpu_has_800M_plla() (cpu_is_at91sam9g20()) 53#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
54 || cpu_is_at91sam9g45())
53 55
54#define cpu_has_pllb() (!cpu_is_at91sam9rl()) 56#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
55 57
56#define cpu_has_upll() (0) 58#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
59 || cpu_is_at91sam9g45()))
60
61#define cpu_has_upll() (cpu_is_at91sam9g45())
57 62
58/* USB host HS & FS */ 63/* USB host HS & FS */
59#define cpu_has_uhp() (!cpu_is_at91sam9rl()) 64#define cpu_has_uhp() (!cpu_is_at91sam9rl())
60 65
61/* USB device FS only */ 66/* USB device FS only */
62#define cpu_has_udpfs() (!cpu_is_at91sam9rl()) 67#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
63 68 || cpu_is_at91sam9g45()))
64 69
65static LIST_HEAD(clocks); 70static LIST_HEAD(clocks);
66static DEFINE_SPINLOCK(clk_lock); 71static DEFINE_SPINLOCK(clk_lock);
@@ -133,6 +138,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
133{ 138{
134 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); 139 unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
135 140
141 if (cpu_is_at91sam9g45()) {
142 if (is_on)
143 uckr |= AT91_PMC_BIASEN;
144 else
145 uckr &= ~AT91_PMC_BIASEN;
146 }
147
136 if (is_on) { 148 if (is_on) {
137 is_on = AT91_PMC_LOCKU; 149 is_on = AT91_PMC_LOCKU;
138 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); 150 at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -310,6 +322,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
310 unsigned long flags; 322 unsigned long flags;
311 unsigned prescale; 323 unsigned prescale;
312 unsigned long actual; 324 unsigned long actual;
325 unsigned long prev = ULONG_MAX;
313 326
314 if (!clk_is_programmable(clk)) 327 if (!clk_is_programmable(clk))
315 return -EINVAL; 328 return -EINVAL;
@@ -317,8 +330,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
317 330
318 actual = clk->parent->rate_hz; 331 actual = clk->parent->rate_hz;
319 for (prescale = 0; prescale < 7; prescale++) { 332 for (prescale = 0; prescale < 7; prescale++) {
320 if (actual && actual <= rate) 333 if (actual > rate)
334 prev = actual;
335
336 if (actual && actual <= rate) {
337 if ((prev - rate) < (rate - actual)) {
338 actual = prev;
339 prescale--;
340 }
321 break; 341 break;
342 }
322 actual >>= 1; 343 actual >>= 1;
323 } 344 }
324 345
@@ -373,6 +394,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
373 return -EBUSY; 394 return -EBUSY;
374 if (!clk_is_primary(parent) || !clk_is_programmable(clk)) 395 if (!clk_is_primary(parent) || !clk_is_programmable(clk))
375 return -EINVAL; 396 return -EINVAL;
397
398 if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB)
399 return -EINVAL;
400
376 spin_lock_irqsave(&clk_lock, flags); 401 spin_lock_irqsave(&clk_lock, flags);
377 402
378 clk->rate_hz = parent->rate_hz; 403 clk->rate_hz = parent->rate_hz;
@@ -601,7 +626,9 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
601 uhpck.pmc_mask = AT91RM9200_PMC_UHP; 626 uhpck.pmc_mask = AT91RM9200_PMC_UHP;
602 udpck.pmc_mask = AT91RM9200_PMC_UDP; 627 udpck.pmc_mask = AT91RM9200_PMC_UDP;
603 at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); 628 at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
604 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { 629 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
630 cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
631 cpu_is_at91sam9g10()) {
605 uhpck.pmc_mask = AT91SAM926x_PMC_UHP; 632 uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
606 udpck.pmc_mask = AT91SAM926x_PMC_UDP; 633 udpck.pmc_mask = AT91SAM926x_PMC_UDP;
607 } else if (cpu_is_at91cap9()) { 634 } else if (cpu_is_at91cap9()) {
@@ -637,6 +664,7 @@ int __init at91_clock_init(unsigned long main_clock)
637{ 664{
638 unsigned tmp, freq, mckr; 665 unsigned tmp, freq, mckr;
639 int i; 666 int i;
667 int pll_overclock = false;
640 668
641 /* 669 /*
642 * When the bootloader initialized the main oscillator correctly, 670 * When the bootloader initialized the main oscillator correctly,
@@ -654,12 +682,25 @@ int __init at91_clock_init(unsigned long main_clock)
654 682
655 /* report if PLLA is more than mildly overclocked */ 683 /* report if PLLA is more than mildly overclocked */
656 plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); 684 plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
657 if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000) 685 if (cpu_has_300M_plla()) {
658 || (cpu_has_800M_plla() && plla.rate_hz > 800000000)) 686 if (plla.rate_hz > 300000000)
687 pll_overclock = true;
688 } else if (cpu_has_800M_plla()) {
689 if (plla.rate_hz > 800000000)
690 pll_overclock = true;
691 } else {
692 if (plla.rate_hz > 209000000)
693 pll_overclock = true;
694 }
695 if (pll_overclock)
659 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); 696 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
660 697
698 if (cpu_is_at91sam9g45()) {
699 mckr = at91_sys_read(AT91_PMC_MCKR);
700 plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
701 }
661 702
662 if (cpu_has_upll() && !cpu_has_pllb()) { 703 if (!cpu_has_pllb() && cpu_has_upll()) {
663 /* setup UTMI clock as the fourth primary clock 704 /* setup UTMI clock as the fourth primary clock
664 * (instead of pllb) */ 705 * (instead of pllb) */
665 utmi_clk.type |= CLK_TYPE_PRIMARY; 706 utmi_clk.type |= CLK_TYPE_PRIMARY;
@@ -701,6 +742,9 @@ int __init at91_clock_init(unsigned long main_clock)
701 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ 742 freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
702 if (mckr & AT91_PMC_PDIV) 743 if (mckr & AT91_PMC_PDIV)
703 freq /= 2; /* processor clock division */ 744 freq /= 2; /* processor clock division */
745 } else if (cpu_is_at91sam9g45()) {
746 mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
747 freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
704 } else { 748 } else {
705 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ 749 mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
706 } 750 }
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index b5daf7f5e011..88e413b38480 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
14extern void __init at91sam9261_initialize(unsigned long main_clock); 14extern void __init at91sam9261_initialize(unsigned long main_clock);
15extern void __init at91sam9263_initialize(unsigned long main_clock); 15extern void __init at91sam9263_initialize(unsigned long main_clock);
16extern void __init at91sam9rl_initialize(unsigned long main_clock); 16extern void __init at91sam9rl_initialize(unsigned long main_clock);
17extern void __init at91sam9g45_initialize(unsigned long main_clock);
17extern void __init at91x40_initialize(unsigned long main_clock); 18extern void __init at91x40_initialize(unsigned long main_clock);
18extern void __init at91cap9_initialize(unsigned long main_clock); 19extern void __init at91cap9_initialize(unsigned long main_clock);
19 20
@@ -23,6 +24,7 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
23extern void __init at91sam9261_init_interrupts(unsigned int priority[]); 24extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
24extern void __init at91sam9263_init_interrupts(unsigned int priority[]); 25extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
25extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); 26extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
27extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
26extern void __init at91x40_init_interrupts(unsigned int priority[]); 28extern void __init at91x40_init_interrupts(unsigned int priority[]);
27extern void __init at91cap9_init_interrupts(unsigned int priority[]); 29extern void __init at91cap9_init_interrupts(unsigned int priority[]);
28extern void __init at91_aic_init(unsigned int priority[]); 30extern void __init at91_aic_init(unsigned int priority[]);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index f2236f0e101f..ae4772e744ac 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -44,13 +44,11 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip,
44 unsigned offset, int val); 44 unsigned offset, int val);
45static int at91_gpiolib_direction_input(struct gpio_chip *chip, 45static int at91_gpiolib_direction_input(struct gpio_chip *chip,
46 unsigned offset); 46 unsigned offset);
47static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
48 47
49#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ 48#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \
50 { \ 49 { \
51 .chip = { \ 50 .chip = { \
52 .label = name, \ 51 .label = name, \
53 .request = at91_gpiolib_request, \
54 .direction_input = at91_gpiolib_direction_input, \ 52 .direction_input = at91_gpiolib_direction_input, \
55 .direction_output = at91_gpiolib_direction_output, \ 53 .direction_output = at91_gpiolib_direction_output, \
56 .get = at91_gpiolib_get, \ 54 .get = at91_gpiolib_get, \
@@ -588,19 +586,6 @@ static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
588 __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); 586 __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
589} 587}
590 588
591static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
592{
593 unsigned pin = chip->base + offset;
594 void __iomem *pio = pin_to_controller(pin);
595 unsigned mask = pin_to_mask(pin);
596
597 /* Cannot request GPIOs that are in alternate function mode */
598 if (!(__raw_readl(pio + PIO_PSR) & mask))
599 return -EPERM;
600
601 return 0;
602}
603
604static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) 589static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
605{ 590{
606 int i; 591 int i;
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
index 3a348ca20773..87de8be17484 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -95,6 +95,9 @@
95#define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */ 95#define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */
96#define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */ 96#define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */
97 97
98#define AT91SAM9G10_SRAM_BASE AT91SAM9261_SRAM_BASE /* Internal SRAM base address */
99#define AT91SAM9G10_SRAM_SIZE 0x00004000 /* Internal SRAM size (16Kb) */
100
98#define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */ 101#define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */
99#define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ 102#define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
100 103
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
new file mode 100644
index 000000000000..a526869aee37
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
@@ -0,0 +1,155 @@
1/*
2 * Chip-specific header file for the AT91SAM9G45 family
3 *
4 * Copyright (C) 2008-2009 Atmel Corporation.
5 *
6 * Common definitions.
7 * Based on AT91SAM9G45 preliminary datasheet.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#ifndef AT91SAM9G45_H
16#define AT91SAM9G45_H
17
18/*
19 * Peripheral identifiers/interrupts.
20 */
21#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
22#define AT91_ID_SYS 1 /* System Controller Interrupt */
23#define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */
24#define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */
25#define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */
26#define AT91SAM9G45_ID_PIODE 5 /* Parallel I/O Controller D and E */
27#define AT91SAM9G45_ID_TRNG 6 /* True Random Number Generator */
28#define AT91SAM9G45_ID_US0 7 /* USART 0 */
29#define AT91SAM9G45_ID_US1 8 /* USART 1 */
30#define AT91SAM9G45_ID_US2 9 /* USART 2 */
31#define AT91SAM9G45_ID_US3 10 /* USART 3 */
32#define AT91SAM9G45_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */
33#define AT91SAM9G45_ID_TWI0 12 /* Two-Wire Interface 0 */
34#define AT91SAM9G45_ID_TWI1 13 /* Two-Wire Interface 1 */
35#define AT91SAM9G45_ID_SPI0 14 /* Serial Peripheral Interface 0 */
36#define AT91SAM9G45_ID_SPI1 15 /* Serial Peripheral Interface 1 */
37#define AT91SAM9G45_ID_SSC0 16 /* Synchronous Serial Controller 0 */
38#define AT91SAM9G45_ID_SSC1 17 /* Synchronous Serial Controller 1 */
39#define AT91SAM9G45_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */
40#define AT91SAM9G45_ID_PWMC 19 /* Pulse Width Modulation Controller */
41#define AT91SAM9G45_ID_TSC 20 /* Touch Screen ADC Controller */
42#define AT91SAM9G45_ID_DMA 21 /* DMA Controller */
43#define AT91SAM9G45_ID_UHPHS 22 /* USB Host High Speed */
44#define AT91SAM9G45_ID_LCDC 23 /* LCD Controller */
45#define AT91SAM9G45_ID_AC97C 24 /* AC97 Controller */
46#define AT91SAM9G45_ID_EMAC 25 /* Ethernet MAC */
47#define AT91SAM9G45_ID_ISI 26 /* Image Sensor Interface */
48#define AT91SAM9G45_ID_UDPHS 27 /* USB Device High Speed */
49#define AT91SAM9G45_ID_AESTDESSHA 28 /* AES + T-DES + SHA */
50#define AT91SAM9G45_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */
51#define AT91SAM9G45_ID_VDEC 30 /* Video Decoder */
52#define AT91SAM9G45_ID_IRQ0 31 /* Advanced Interrupt Controller */
53
54/*
55 * User Peripheral physical base addresses.
56 */
57#define AT91SAM9G45_BASE_UDPHS 0xfff78000
58#define AT91SAM9G45_BASE_TCB0 0xfff7c000
59#define AT91SAM9G45_BASE_TC0 0xfff7c000
60#define AT91SAM9G45_BASE_TC1 0xfff7c040
61#define AT91SAM9G45_BASE_TC2 0xfff7c080
62#define AT91SAM9G45_BASE_MCI0 0xfff80000
63#define AT91SAM9G45_BASE_TWI0 0xfff84000
64#define AT91SAM9G45_BASE_TWI1 0xfff88000
65#define AT91SAM9G45_BASE_US0 0xfff8c000
66#define AT91SAM9G45_BASE_US1 0xfff90000
67#define AT91SAM9G45_BASE_US2 0xfff94000
68#define AT91SAM9G45_BASE_US3 0xfff98000
69#define AT91SAM9G45_BASE_SSC0 0xfff9c000
70#define AT91SAM9G45_BASE_SSC1 0xfffa0000
71#define AT91SAM9G45_BASE_SPI0 0xfffa4000
72#define AT91SAM9G45_BASE_SPI1 0xfffa8000
73#define AT91SAM9G45_BASE_AC97C 0xfffac000
74#define AT91SAM9G45_BASE_TSC 0xfffb0000
75#define AT91SAM9G45_BASE_ISI 0xfffb4000
76#define AT91SAM9G45_BASE_PWMC 0xfffb8000
77#define AT91SAM9G45_BASE_EMAC 0xfffbc000
78#define AT91SAM9G45_BASE_AES 0xfffc0000
79#define AT91SAM9G45_BASE_TDES 0xfffc4000
80#define AT91SAM9G45_BASE_SHA 0xfffc8000
81#define AT91SAM9G45_BASE_TRNG 0xfffcc000
82#define AT91SAM9G45_BASE_MCI1 0xfffd0000
83#define AT91SAM9G45_BASE_TCB1 0xfffd4000
84#define AT91SAM9G45_BASE_TC3 0xfffd4000
85#define AT91SAM9G45_BASE_TC4 0xfffd4040
86#define AT91SAM9G45_BASE_TC5 0xfffd4080
87#define AT91_BASE_SYS 0xffffe200
88
89/*
90 * System Peripherals (offset from AT91_BASE_SYS)
91 */
92#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
93#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS)
94#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
95#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
96#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
97#define AT91_DMA (0xffffec00 - AT91_BASE_SYS)
98#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
99#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
100#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
101#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
102#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
103#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
104#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
105#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
106#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
107#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
108#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
109#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
110#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
111#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
112#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS)
113
114#define AT91_USART0 AT91SAM9G45_BASE_US0
115#define AT91_USART1 AT91SAM9G45_BASE_US1
116#define AT91_USART2 AT91SAM9G45_BASE_US2
117#define AT91_USART3 AT91SAM9G45_BASE_US3
118
119/*
120 * Internal Memory.
121 */
122#define AT91SAM9G45_SRAM_BASE 0x00300000 /* Internal SRAM base address */
123#define AT91SAM9G45_SRAM_SIZE SZ_64K /* Internal SRAM size (64Kb) */
124
125#define AT91SAM9G45_ROM_BASE 0x00400000 /* Internal ROM base address */
126#define AT91SAM9G45_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */
127
128#define AT91SAM9G45_LCDC_BASE 0x00500000 /* LCD Controller */
129#define AT91SAM9G45_UDPHS_FIFO 0x00600000 /* USB Device HS controller */
130#define AT91SAM9G45_OHCI_BASE 0x00700000 /* USB Host controller (OHCI) */
131#define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */
132#define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */
133
134#define CONFIG_DRAM_BASE AT91_CHIPSELECT_6
135
136#define CONSISTENT_DMA_SIZE SZ_4M
137
138/*
139 * DMA peripheral identifiers
140 * for hardware handshaking interface
141 */
142#define AT_DMA_ID_MCI0 0
143#define AT_DMA_ID_SPI0_TX 1
144#define AT_DMA_ID_SPI0_RX 2
145#define AT_DMA_ID_SPI1_TX 3
146#define AT_DMA_ID_SPI1_RX 4
147#define AT_DMA_ID_SSC0_TX 5
148#define AT_DMA_ID_SSC0_RX 6
149#define AT_DMA_ID_SSC1_TX 7
150#define AT_DMA_ID_SSC1_RX 8
151#define AT_DMA_ID_AC97_TX 9
152#define AT_DMA_ID_AC97_RX 10
153#define AT_DMA_ID_MCI1 13
154
155#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
new file mode 100644
index 000000000000..c972d60e0aeb
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
@@ -0,0 +1,153 @@
1/*
2 * Matrix-centric header file for the AT91SAM9G45 family
3 *
4 * Copyright (C) 2008-2009 Atmel Corporation.
5 *
6 * Memory Controllers (MATRIX, EBI) - System peripherals registers.
7 * Based on AT91SAM9G45 preliminary datasheet.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#ifndef AT91SAM9G45_MATRIX_H
16#define AT91SAM9G45_MATRIX_H
17
18#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
19#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
20#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
21#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
22#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
23#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
24#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
25#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
26#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
27#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */
28#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */
29#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */
30#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
31#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
32#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
33#define AT91_MATRIX_ULBT_FOUR (2 << 0)
34#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
35#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
36#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0)
37#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0)
38#define AT91_MATRIX_ULBT_128 (7 << 0)
39
40#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
41#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
42#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
43#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
44#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
45#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
46#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
47#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
48#define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */
49#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
50#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
51#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
52#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
53#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
54
55#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
56#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
57#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
58#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
59#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
60#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
61#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
62#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
63#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
64#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
65#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
66#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
67#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
68#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
69#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
70#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
71#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
72#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
73#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
74#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
75#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
76#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
77#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
78#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
79#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
80#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */
81#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */
82#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */
83
84#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
85#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
86#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
87#define AT91_MATRIX_RCB2 (1 << 2)
88#define AT91_MATRIX_RCB3 (1 << 3)
89#define AT91_MATRIX_RCB4 (1 << 4)
90#define AT91_MATRIX_RCB5 (1 << 5)
91#define AT91_MATRIX_RCB6 (1 << 6)
92#define AT91_MATRIX_RCB7 (1 << 7)
93#define AT91_MATRIX_RCB8 (1 << 8)
94#define AT91_MATRIX_RCB9 (1 << 9)
95#define AT91_MATRIX_RCB10 (1 << 10)
96#define AT91_MATRIX_RCB11 (1 << 11)
97
98#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */
99#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
100#define AT91_MATRIX_ITCM_0 (0 << 0)
101#define AT91_MATRIX_ITCM_32 (6 << 0)
102#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
103#define AT91_MATRIX_DTCM_0 (0 << 4)
104#define AT91_MATRIX_DTCM_32 (6 << 4)
105#define AT91_MATRIX_DTCM_64 (7 << 4)
106#define AT91_MATRIX_TCM_NWS (0x1 << 11) /* Wait state TCM register */
107#define AT91_MATRIX_TCM_NO_WS (0x0 << 11)
108#define AT91_MATRIX_TCM_ONE_WS (0x1 << 11)
109
110#define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */
111#define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */
112#define AT91C_VDEC_SEL_OFF (0 << 0)
113#define AT91C_VDEC_SEL_ON (1 << 0)
114
115#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */
116#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
117#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
118#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
119#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
120#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
121#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
122#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */
123#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4)
124#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4)
125#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */
126#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5)
127#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5)
128#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
129#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
130#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
131#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
132#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
133#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
134#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
135#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
136#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
137#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
138#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
139#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
140
141#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
142#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
143#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
144#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
145#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
146
147#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
148#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
149#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
150#define AT91_MATRIX_WPSR_WPV (1 << 0)
151#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
152
153#endif
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index e6afff849b85..13f27a4b882d 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -37,6 +37,7 @@
37#include <linux/leds.h> 37#include <linux/leds.h>
38#include <linux/spi/spi.h> 38#include <linux/spi/spi.h>
39#include <linux/usb/atmel_usba_udc.h> 39#include <linux/usb/atmel_usba_udc.h>
40#include <sound/atmel-ac97c.h>
40 41
41 /* USB Device */ 42 /* USB Device */
42struct at91_udc_data { 43struct at91_udc_data {
@@ -80,7 +81,8 @@ struct at91_eth_data {
80}; 81};
81extern void __init at91_add_device_eth(struct at91_eth_data *data); 82extern void __init at91_add_device_eth(struct at91_eth_data *data);
82 83
83#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) 84#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
85 || defined(CONFIG_ARCH_AT91SAM9G45)
84#define eth_platform_data at91_eth_data 86#define eth_platform_data at91_eth_data
85#endif 87#endif
86 88
@@ -90,6 +92,7 @@ struct at91_usbh_data {
90 u8 vbus_pin[2]; /* port power-control pin */ 92 u8 vbus_pin[2]; /* port power-control pin */
91}; 93};
92extern void __init at91_add_device_usbh(struct at91_usbh_data *data); 94extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
95extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
93 96
94 /* NAND / SmartMedia */ 97 /* NAND / SmartMedia */
95struct atmel_nand_data { 98struct atmel_nand_data {
@@ -105,7 +108,11 @@ struct atmel_nand_data {
105extern void __init at91_add_device_nand(struct atmel_nand_data *data); 108extern void __init at91_add_device_nand(struct atmel_nand_data *data);
106 109
107 /* I2C*/ 110 /* I2C*/
111#if defined(CONFIG_ARCH_AT91SAM9G45)
112extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices);
113#else
108extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); 114extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
115#endif
109 116
110 /* SPI */ 117 /* SPI */
111extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); 118extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
@@ -168,10 +175,7 @@ struct atmel_lcdfb_info;
168extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); 175extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
169 176
170 /* AC97 */ 177 /* AC97 */
171struct atmel_ac97_data { 178extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
172 u8 reset_pin; /* reset */
173};
174extern void __init at91_add_device_ac97(struct atmel_ac97_data *data);
175 179
176 /* ISI */ 180 /* ISI */
177extern void __init at91_add_device_isi(void); 181extern void __init at91_add_device_isi(void);
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index c554c3e4d553..34a9502c48bc 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -21,8 +21,10 @@
21#define ARCH_ID_AT91SAM9260 0x019803a0 21#define ARCH_ID_AT91SAM9260 0x019803a0
22#define ARCH_ID_AT91SAM9261 0x019703a0 22#define ARCH_ID_AT91SAM9261 0x019703a0
23#define ARCH_ID_AT91SAM9263 0x019607a0 23#define ARCH_ID_AT91SAM9263 0x019607a0
24#define ARCH_ID_AT91SAM9G10 0x819903a0
24#define ARCH_ID_AT91SAM9G20 0x019905a0 25#define ARCH_ID_AT91SAM9G20 0x019905a0
25#define ARCH_ID_AT91SAM9RL64 0x019b03a0 26#define ARCH_ID_AT91SAM9RL64 0x019b03a0
27#define ARCH_ID_AT91SAM9G45 0x819b05a0
26#define ARCH_ID_AT91CAP9 0x039A03A0 28#define ARCH_ID_AT91CAP9 0x039A03A0
27 29
28#define ARCH_ID_AT91SAM9XE128 0x329973a0 30#define ARCH_ID_AT91SAM9XE128 0x329973a0
@@ -39,6 +41,15 @@ static inline unsigned long at91_cpu_identify(void)
39 return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); 41 return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
40} 42}
41 43
44#define ARCH_EXID_AT91SAM9M11 0x00000001
45#define ARCH_EXID_AT91SAM9M10 0x00000002
46#define ARCH_EXID_AT91SAM9G45 0x00000004
47
48static inline unsigned long at91_exid_identify(void)
49{
50 return at91_sys_read(AT91_DBGU_EXID);
51}
52
42 53
43#define ARCH_FAMILY_AT91X92 0x09200000 54#define ARCH_FAMILY_AT91X92 0x09200000
44#define ARCH_FAMILY_AT91SAM9 0x01900000 55#define ARCH_FAMILY_AT91SAM9 0x01900000
@@ -87,6 +98,12 @@ static inline unsigned long at91cap9_rev_identify(void)
87#define cpu_is_at91sam9261() (0) 98#define cpu_is_at91sam9261() (0)
88#endif 99#endif
89 100
101#ifdef CONFIG_ARCH_AT91SAM9G10
102#define cpu_is_at91sam9g10() (at91_cpu_identify() == ARCH_ID_AT91SAM9G10)
103#else
104#define cpu_is_at91sam9g10() (0)
105#endif
106
90#ifdef CONFIG_ARCH_AT91SAM9263 107#ifdef CONFIG_ARCH_AT91SAM9263
91#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263) 108#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263)
92#else 109#else
@@ -99,6 +116,12 @@ static inline unsigned long at91cap9_rev_identify(void)
99#define cpu_is_at91sam9rl() (0) 116#define cpu_is_at91sam9rl() (0)
100#endif 117#endif
101 118
119#ifdef CONFIG_ARCH_AT91SAM9G45
120#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
121#else
122#define cpu_is_at91sam9g45() (0)
123#endif
124
102#ifdef CONFIG_ARCH_AT91CAP9 125#ifdef CONFIG_ARCH_AT91CAP9
103#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) 126#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
104#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) 127#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index da0b681c652c..a0df8b022df2 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -20,12 +20,14 @@
20#include <mach/at91rm9200.h> 20#include <mach/at91rm9200.h>
21#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) 21#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
22#include <mach/at91sam9260.h> 22#include <mach/at91sam9260.h>
23#elif defined(CONFIG_ARCH_AT91SAM9261) 23#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)
24#include <mach/at91sam9261.h> 24#include <mach/at91sam9261.h>
25#elif defined(CONFIG_ARCH_AT91SAM9263) 25#elif defined(CONFIG_ARCH_AT91SAM9263)
26#include <mach/at91sam9263.h> 26#include <mach/at91sam9263.h>
27#elif defined(CONFIG_ARCH_AT91SAM9RL) 27#elif defined(CONFIG_ARCH_AT91SAM9RL)
28#include <mach/at91sam9rl.h> 28#include <mach/at91sam9rl.h>
29#elif defined(CONFIG_ARCH_AT91SAM9G45)
30#include <mach/at91sam9g45.h>
29#elif defined(CONFIG_ARCH_AT91CAP9) 31#elif defined(CONFIG_ARCH_AT91CAP9)
30#include <mach/at91cap9.h> 32#include <mach/at91cap9.h>
31#elif defined(CONFIG_ARCH_AT91X40) 33#elif defined(CONFIG_ARCH_AT91X40)
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
index d84c9948becf..31ac2d97f14c 100644
--- a/arch/arm/mach-at91/include/mach/timex.h
+++ b/arch/arm/mach-at91/include/mach/timex.h
@@ -42,6 +42,11 @@
42#define AT91SAM9_MASTER_CLOCK 99300000 42#define AT91SAM9_MASTER_CLOCK 99300000
43#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) 43#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
44 44
45#elif defined(CONFIG_ARCH_AT91SAM9G10)
46
47#define AT91SAM9_MASTER_CLOCK 133000000
48#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
49
45#elif defined(CONFIG_ARCH_AT91SAM9263) 50#elif defined(CONFIG_ARCH_AT91SAM9263)
46 51
47#if defined(CONFIG_MACH_USB_A9263) 52#if defined(CONFIG_MACH_USB_A9263)
@@ -62,6 +67,11 @@
62#define AT91SAM9_MASTER_CLOCK 132096000 67#define AT91SAM9_MASTER_CLOCK 132096000
63#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) 68#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
64 69
70#elif defined(CONFIG_ARCH_AT91SAM9G45)
71
72#define AT91SAM9_MASTER_CLOCK 133333333
73#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
74
65#elif defined(CONFIG_ARCH_AT91CAP9) 75#elif defined(CONFIG_ARCH_AT91CAP9)
66 76
67#define AT91CAP9_MASTER_CLOCK 100000000 77#define AT91CAP9_MASTER_CLOCK 100000000
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index e26c4fe61fae..4028724d490d 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -201,7 +201,8 @@ static int at91_pm_verify_clocks(void)
201 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); 201 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
202 return 0; 202 return 0;
203 } 203 }
204 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { 204 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
205 || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
205 if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { 206 if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
206 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); 207 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
207 return 0; 208 return 0;
diff --git a/arch/arm/mach-bcmring/Kconfig b/arch/arm/mach-bcmring/Kconfig
new file mode 100644
index 000000000000..457b4384913e
--- /dev/null
+++ b/arch/arm/mach-bcmring/Kconfig
@@ -0,0 +1,21 @@
1choice
2 prompt "Processor selection in BCMRING family of devices"
3 depends on ARCH_BCMRING
4 default ARCH_BCM11107
5
6config ARCH_FPGA11107
7 bool "FPGA11107"
8
9config ARCH_BCM11107
10 bool "BCM11107"
11endchoice
12
13menu "BCMRING Options"
14 depends on ARCH_BCMRING
15
16config BCM_ZRELADDR
17 hex "Compressed ZREL ADDR"
18
19endmenu
20
21# source "drivers/char/bcmring/Kconfig"
diff --git a/arch/arm/mach-bcmring/Makefile b/arch/arm/mach-bcmring/Makefile
new file mode 100644
index 000000000000..f8d9fcedf917
--- /dev/null
+++ b/arch/arm/mach-bcmring/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Object file lists.
6
7obj-y := arch.o mm.o irq.o clock.o core.o timer.o dma.o
8obj-y += csp/
diff --git a/arch/arm/mach-bcmring/Makefile.boot b/arch/arm/mach-bcmring/Makefile.boot
new file mode 100644
index 000000000000..fb53b283bebb
--- /dev/null
+++ b/arch/arm/mach-bcmring/Makefile.boot
@@ -0,0 +1,6 @@
1# Address where decompressor will be written and eventually executed.
2#
3# default to SDRAM
4zreladdr-y := $(CONFIG_BCM_ZRELADDR)
5params_phys-y := 0x00000800
6
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
new file mode 100644
index 000000000000..0da693b0f7e1
--- /dev/null
+++ b/arch/arm/mach-bcmring/arch.c
@@ -0,0 +1,157 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#include <linux/kernel.h>
16#include <linux/platform_device.h>
17#include <linux/types.h>
18#include <linux/sched.h>
19#include <linux/interrupt.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/spinlock.h>
23#include <linux/module.h>
24
25#include <linux/proc_fs.h>
26#include <linux/sysctl.h>
27
28#include <asm/irq.h>
29#include <asm/setup.h>
30#include <asm/mach-types.h>
31#include <asm/mach/time.h>
32
33#include <asm/mach/arch.h>
34#include <mach/dma.h>
35#include <mach/hardware.h>
36#include <mach/csp/mm_io.h>
37#include <mach/csp/chipcHw_def.h>
38#include <mach/csp/chipcHw_inline.h>
39
40#include <cfg_global.h>
41
42#include "core.h"
43
44HW_DECLARE_SPINLOCK(arch)
45HW_DECLARE_SPINLOCK(gpio)
46#if defined(CONFIG_DEBUG_SPINLOCK)
47 EXPORT_SYMBOL(bcmring_gpio_reg_lock);
48#endif
49
50/* FIXME: temporary solution */
51#define BCM_SYSCTL_REBOOT_WARM 1
52#define CTL_BCM_REBOOT 112
53
54/* sysctl */
55int bcmring_arch_warm_reboot; /* do a warm reboot on hard reset */
56
57static struct ctl_table_header *bcmring_sysctl_header;
58
59static struct ctl_table bcmring_sysctl_warm_reboot[] = {
60 {
61 .ctl_name = BCM_SYSCTL_REBOOT_WARM,
62 .procname = "warm",
63 .data = &bcmring_arch_warm_reboot,
64 .maxlen = sizeof(int),
65 .mode = 0644,
66 .proc_handler = &proc_dointvec},
67 {}
68};
69
70static struct ctl_table bcmring_sysctl_reboot[] = {
71 {
72 .ctl_name = CTL_BCM_REBOOT,
73 .procname = "reboot",
74 .mode = 0555,
75 .child = bcmring_sysctl_warm_reboot},
76 {}
77};
78
79static struct platform_device nand_device = {
80 .name = "bcm-nand",
81 .id = -1,
82};
83
84static struct platform_device *devices[] __initdata = {
85 &nand_device,
86};
87
88/****************************************************************************
89*
90* Called from the customize_machine function in arch/arm/kernel/setup.c
91*
92* The customize_machine function is tagged as an arch_initcall
93* (see include/linux/init.h for the order that the various init sections
94* are called in.
95*
96*****************************************************************************/
97static void __init bcmring_init_machine(void)
98{
99
100 bcmring_sysctl_header = register_sysctl_table(bcmring_sysctl_reboot);
101
102 /* Enable spread spectrum */
103 chipcHw_enableSpreadSpectrum();
104
105 platform_add_devices(devices, ARRAY_SIZE(devices));
106
107 bcmring_amba_init();
108
109 dma_init();
110}
111
112/****************************************************************************
113*
114* Called from setup_arch (in arch/arm/kernel/setup.c) to fixup any tags
115* passed in by the boot loader.
116*
117*****************************************************************************/
118
119static void __init bcmring_fixup(struct machine_desc *desc,
120 struct tag *t, char **cmdline, struct meminfo *mi) {
121#ifdef CONFIG_BLK_DEV_INITRD
122 printk(KERN_NOTICE "bcmring_fixup\n");
123 t->hdr.tag = ATAG_CORE;
124 t->hdr.size = tag_size(tag_core);
125 t->u.core.flags = 0;
126 t->u.core.pagesize = PAGE_SIZE;
127 t->u.core.rootdev = 31 << 8 | 0;
128 t = tag_next(t);
129
130 t->hdr.tag = ATAG_MEM;
131 t->hdr.size = tag_size(tag_mem32);
132 t->u.mem.start = CFG_GLOBAL_RAM_BASE;
133 t->u.mem.size = CFG_GLOBAL_RAM_SIZE;
134
135 t = tag_next(t);
136
137 t->hdr.tag = ATAG_NONE;
138 t->hdr.size = 0;
139#endif
140}
141
142/****************************************************************************
143*
144* Machine Description
145*
146*****************************************************************************/
147
148MACHINE_START(BCMRING, "BCMRING")
149 /* Maintainer: Broadcom Corporation */
150 .phys_io = MM_IO_START,
151 .io_pg_offst = (MM_IO_BASE >> 18) & 0xfffc,
152 .fixup = bcmring_fixup,
153 .map_io = bcmring_map_io,
154 .init_irq = bcmring_init_irq,
155 .timer = &bcmring_timer,
156 .init_machine = bcmring_init_machine
157MACHINE_END
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c
new file mode 100644
index 000000000000..14bafc38f2dc
--- /dev/null
+++ b/arch/arm/mach-bcmring/clock.c
@@ -0,0 +1,224 @@
1/*****************************************************************************
2* Copyright 2001 - 2009 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/device.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/err.h>
21#include <linux/string.h>
22#include <linux/clk.h>
23#include <linux/spinlock.h>
24#include <mach/csp/hw_cfg.h>
25#include <mach/csp/chipcHw_def.h>
26#include <mach/csp/chipcHw_reg.h>
27#include <mach/csp/chipcHw_inline.h>
28
29#include <asm/clkdev.h>
30
31#include "clock.h"
32
33#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
34#define clk_is_pll1(x) ((x)->type & CLK_TYPE_PLL1)
35#define clk_is_pll2(x) ((x)->type & CLK_TYPE_PLL2)
36#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE)
37#define clk_is_bypassable(x) ((x)->type & CLK_TYPE_BYPASSABLE)
38
39#define clk_is_using_xtal(x) ((x)->mode & CLK_MODE_XTAL)
40
41static DEFINE_SPINLOCK(clk_lock);
42
43static void __clk_enable(struct clk *clk)
44{
45 if (!clk)
46 return;
47
48 /* enable parent clock first */
49 if (clk->parent)
50 __clk_enable(clk->parent);
51
52 if (clk->use_cnt++ == 0) {
53 if (clk_is_pll1(clk)) { /* PLL1 */
54 chipcHw_pll1Enable(clk->rate_hz, 0);
55 } else if (clk_is_pll2(clk)) { /* PLL2 */
56 chipcHw_pll2Enable(clk->rate_hz);
57 } else if (clk_is_using_xtal(clk)) { /* source is crystal */
58 if (!clk_is_primary(clk))
59 chipcHw_bypassClockEnable(clk->csp_id);
60 } else { /* source is PLL */
61 chipcHw_setClockEnable(clk->csp_id);
62 }
63 }
64}
65
66int clk_enable(struct clk *clk)
67{
68 unsigned long flags;
69
70 if (!clk)
71 return -EINVAL;
72
73 spin_lock_irqsave(&clk_lock, flags);
74 __clk_enable(clk);
75 spin_unlock_irqrestore(&clk_lock, flags);
76
77 return 0;
78}
79EXPORT_SYMBOL(clk_enable);
80
81static void __clk_disable(struct clk *clk)
82{
83 if (!clk)
84 return;
85
86 BUG_ON(clk->use_cnt == 0);
87
88 if (--clk->use_cnt == 0) {
89 if (clk_is_pll1(clk)) { /* PLL1 */
90 chipcHw_pll1Disable();
91 } else if (clk_is_pll2(clk)) { /* PLL2 */
92 chipcHw_pll2Disable();
93 } else if (clk_is_using_xtal(clk)) { /* source is crystal */
94 if (!clk_is_primary(clk))
95 chipcHw_bypassClockDisable(clk->csp_id);
96 } else { /* source is PLL */
97 chipcHw_setClockDisable(clk->csp_id);
98 }
99 }
100
101 if (clk->parent)
102 __clk_disable(clk->parent);
103}
104
105void clk_disable(struct clk *clk)
106{
107 unsigned long flags;
108
109 if (!clk)
110 return;
111
112 spin_lock_irqsave(&clk_lock, flags);
113 __clk_disable(clk);
114 spin_unlock_irqrestore(&clk_lock, flags);
115}
116EXPORT_SYMBOL(clk_disable);
117
118unsigned long clk_get_rate(struct clk *clk)
119{
120 if (!clk)
121 return 0;
122
123 return clk->rate_hz;
124}
125EXPORT_SYMBOL(clk_get_rate);
126
127long clk_round_rate(struct clk *clk, unsigned long rate)
128{
129 unsigned long flags;
130 unsigned long actual;
131 unsigned long rate_hz;
132
133 if (!clk)
134 return -EINVAL;
135
136 if (!clk_is_programmable(clk))
137 return -EINVAL;
138
139 if (clk->use_cnt)
140 return -EBUSY;
141
142 spin_lock_irqsave(&clk_lock, flags);
143 actual = clk->parent->rate_hz;
144 rate_hz = min(actual, rate);
145 spin_unlock_irqrestore(&clk_lock, flags);
146
147 return rate_hz;
148}
149EXPORT_SYMBOL(clk_round_rate);
150
151int clk_set_rate(struct clk *clk, unsigned long rate)
152{
153 unsigned long flags;
154 unsigned long actual;
155 unsigned long rate_hz;
156
157 if (!clk)
158 return -EINVAL;
159
160 if (!clk_is_programmable(clk))
161 return -EINVAL;
162
163 if (clk->use_cnt)
164 return -EBUSY;
165
166 spin_lock_irqsave(&clk_lock, flags);
167 actual = clk->parent->rate_hz;
168 rate_hz = min(actual, rate);
169 rate_hz = chipcHw_setClockFrequency(clk->csp_id, rate_hz);
170 clk->rate_hz = rate_hz;
171 spin_unlock_irqrestore(&clk_lock, flags);
172
173 return 0;
174}
175EXPORT_SYMBOL(clk_set_rate);
176
177struct clk *clk_get_parent(struct clk *clk)
178{
179 if (!clk)
180 return NULL;
181
182 return clk->parent;
183}
184EXPORT_SYMBOL(clk_get_parent);
185
186int clk_set_parent(struct clk *clk, struct clk *parent)
187{
188 unsigned long flags;
189 struct clk *old_parent;
190
191 if (!clk || !parent)
192 return -EINVAL;
193
194 if (!clk_is_primary(parent) || !clk_is_bypassable(clk))
195 return -EINVAL;
196
197 /* if more than one user, parent is not allowed */
198 if (clk->use_cnt > 1)
199 return -EBUSY;
200
201 if (clk->parent == parent)
202 return 0;
203
204 spin_lock_irqsave(&clk_lock, flags);
205 old_parent = clk->parent;
206 clk->parent = parent;
207 if (clk_is_using_xtal(parent))
208 clk->mode |= CLK_MODE_XTAL;
209 else
210 clk->mode &= (~CLK_MODE_XTAL);
211
212 /* if clock is active */
213 if (clk->use_cnt != 0) {
214 clk->use_cnt--;
215 /* enable clock with the new parent */
216 __clk_enable(clk);
217 /* disable the old parent */
218 __clk_disable(old_parent);
219 }
220 spin_unlock_irqrestore(&clk_lock, flags);
221
222 return 0;
223}
224EXPORT_SYMBOL(clk_set_parent);
diff --git a/arch/arm/mach-bcmring/clock.h b/arch/arm/mach-bcmring/clock.h
new file mode 100644
index 000000000000..5e0b98138973
--- /dev/null
+++ b/arch/arm/mach-bcmring/clock.h
@@ -0,0 +1,33 @@
1/*****************************************************************************
2* Copyright 2001 - 2009 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14#include <mach/csp/chipcHw_def.h>
15
16#define CLK_TYPE_PRIMARY 1 /* primary clock must NOT have a parent */
17#define CLK_TYPE_PLL1 2 /* PPL1 */
18#define CLK_TYPE_PLL2 4 /* PPL2 */
19#define CLK_TYPE_PROGRAMMABLE 8 /* programmable clock rate */
20#define CLK_TYPE_BYPASSABLE 16 /* parent can be changed */
21
22#define CLK_MODE_XTAL 1 /* clock source is from crystal */
23
24struct clk {
25 const char *name; /* clock name */
26 unsigned int type; /* clock type */
27 unsigned int mode; /* current mode */
28 volatile int use_bypass; /* indicate if it's in bypass mode */
29 chipcHw_CLOCK_e csp_id; /* clock ID for CSP CHIPC */
30 unsigned long rate_hz; /* clock rate in Hz */
31 unsigned int use_cnt; /* usage count */
32 struct clk *parent; /* parent clock */
33};
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
new file mode 100644
index 000000000000..492c649f451e
--- /dev/null
+++ b/arch/arm/mach-bcmring/core.c
@@ -0,0 +1,367 @@
1/*
2 * derived from linux/arch/arm/mach-versatile/core.c
3 * linux/arch/arm/mach-bcmring/core.c
4 *
5 * Copyright (C) 1999 - 2003 ARM Limited
6 * Copyright (C) 2000 Deep Blue Solutions Ltd
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22/* Portions copyright Broadcom 2008 */
23
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/dma-mapping.h>
27#include <linux/platform_device.h>
28#include <linux/sysdev.h>
29#include <linux/interrupt.h>
30#include <linux/amba/bus.h>
31#include <linux/clocksource.h>
32#include <linux/clockchips.h>
33
34#include <linux/amba/bus.h>
35#include <mach/csp/mm_addr.h>
36#include <mach/hardware.h>
37#include <asm/clkdev.h>
38#include <linux/io.h>
39#include <asm/irq.h>
40#include <asm/hardware/arm_timer.h>
41#include <asm/mach-types.h>
42
43#include <asm/mach/arch.h>
44#include <asm/mach/flash.h>
45#include <asm/mach/irq.h>
46#include <asm/mach/time.h>
47#include <asm/mach/map.h>
48#include <asm/mach/mmc.h>
49
50#include <cfg_global.h>
51
52#include "clock.h"
53
54#include <csp/secHw.h>
55#include <mach/csp/secHw_def.h>
56#include <mach/csp/chipcHw_inline.h>
57#include <mach/csp/tmrHw_reg.h>
58
59#define AMBA_DEVICE(name, initname, base, plat, size) \
60static struct amba_device name##_device = { \
61 .dev = { \
62 .coherent_dma_mask = ~0, \
63 .init_name = initname, \
64 .platform_data = plat \
65 }, \
66 .res = { \
67 .start = MM_ADDR_IO_##base, \
68 .end = MM_ADDR_IO_##base + (size) - 1, \
69 .flags = IORESOURCE_MEM \
70 }, \
71 .dma_mask = ~0, \
72 .irq = { \
73 IRQ_##base \
74 } \
75}
76
77
78AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K);
79AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K);
80
81static struct clk pll1_clk = {
82 .name = "PLL1",
83 .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL1,
84 .rate_hz = 2000000000,
85 .use_cnt = 7,
86};
87
88static struct clk uart_clk = {
89 .name = "UART",
90 .type = CLK_TYPE_PROGRAMMABLE,
91 .csp_id = chipcHw_CLOCK_UART,
92 .rate_hz = HW_CFG_UART_CLK_HZ,
93 .parent = &pll1_clk,
94};
95
96static struct clk_lookup lookups[] = {
97 { /* UART0 */
98 .dev_id = "uarta",
99 .clk = &uart_clk,
100 }, { /* UART1 */
101 .dev_id = "uartb",
102 .clk = &uart_clk,
103 }
104};
105
106static struct amba_device *amba_devs[] __initdata = {
107 &uartA_device,
108 &uartB_device,
109};
110
111void __init bcmring_amba_init(void)
112{
113 int i;
114 u32 bus_clock;
115
116/* Linux is run initially in non-secure mode. Secure peripherals */
117/* generate FIQ, and must be handled in secure mode. Until we have */
118/* a linux security monitor implementation, keep everything in */
119/* non-secure mode. */
120 chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_SPU);
121 secHw_setUnsecure(secHw_BLK_MASK_CHIP_CONTROL |
122 secHw_BLK_MASK_KEY_SCAN |
123 secHw_BLK_MASK_TOUCH_SCREEN |
124 secHw_BLK_MASK_UART0 |
125 secHw_BLK_MASK_UART1 |
126 secHw_BLK_MASK_WATCHDOG |
127 secHw_BLK_MASK_SPUM |
128 secHw_BLK_MASK_DDR2 |
129 secHw_BLK_MASK_SPU |
130 secHw_BLK_MASK_PKA |
131 secHw_BLK_MASK_RNG |
132 secHw_BLK_MASK_RTC |
133 secHw_BLK_MASK_OTP |
134 secHw_BLK_MASK_BOOT |
135 secHw_BLK_MASK_MPU |
136 secHw_BLK_MASK_TZCTRL | secHw_BLK_MASK_INTR);
137
138 /* Only the devices attached to the AMBA bus are enabled just before the bus is */
139 /* scanned and the drivers are loaded. The clocks need to be on for the AMBA bus */
140 /* driver to access these blocks. The bus is probed, and the drivers are loaded. */
141 /* FIXME Need to remove enable of PIF once CLCD clock enable used properly in FPGA. */
142 bus_clock = chipcHw_REG_BUS_CLOCK_GE
143 | chipcHw_REG_BUS_CLOCK_SDIO0 | chipcHw_REG_BUS_CLOCK_SDIO1;
144
145 chipcHw_busInterfaceClockEnable(bus_clock);
146
147 for (i = 0; i < ARRAY_SIZE(lookups); i++)
148 clkdev_add(&lookups[i]);
149
150 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
151 struct amba_device *d = amba_devs[i];
152 amba_device_register(d, &iomem_resource);
153 }
154}
155
156/*
157 * Where is the timer (VA)?
158 */
159#define TIMER0_VA_BASE MM_IO_BASE_TMR
160#define TIMER1_VA_BASE (MM_IO_BASE_TMR + 0x20)
161#define TIMER2_VA_BASE (MM_IO_BASE_TMR + 0x40)
162#define TIMER3_VA_BASE (MM_IO_BASE_TMR + 0x60)
163
164/* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically 150-166 MHz */
165#if defined(CONFIG_ARCH_FPGA11107)
166/* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
167/* slow down Linux's sense of time */
168#define TIMER0_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30)
169#define TIMER1_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30)
170#define TIMER3_FREQUENCY_MHZ (tmrHw_HIGH_FREQUENCY_MHZ * 30)
171#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
172#else
173#define TIMER0_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ
174#define TIMER1_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ
175#define TIMER3_FREQUENCY_MHZ tmrHw_HIGH_FREQUENCY_MHZ
176#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000)
177#endif
178
179#define TICKS_PER_uSEC TIMER0_FREQUENCY_MHZ
180
181/*
182 * These are useconds NOT ticks.
183 *
184 */
185#define mSEC_1 1000
186#define mSEC_5 (mSEC_1 * 5)
187#define mSEC_10 (mSEC_1 * 10)
188#define mSEC_25 (mSEC_1 * 25)
189#define SEC_1 (mSEC_1 * 1000)
190
191/*
192 * How long is the timer interval?
193 */
194#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
195#if TIMER_INTERVAL >= 0x100000
196#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
197#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
198#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
199#elif TIMER_INTERVAL >= 0x10000
200#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
201#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
202#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
203#else
204#define TIMER_RELOAD (TIMER_INTERVAL)
205#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
206#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
207#endif
208
209static void timer_set_mode(enum clock_event_mode mode,
210 struct clock_event_device *clk)
211{
212 unsigned long ctrl;
213
214 switch (mode) {
215 case CLOCK_EVT_MODE_PERIODIC:
216 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
217
218 ctrl = TIMER_CTRL_PERIODIC;
219 ctrl |=
220 TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE |
221 TIMER_CTRL_ENABLE;
222 break;
223 case CLOCK_EVT_MODE_ONESHOT:
224 /* period set, and timer enabled in 'next_event' hook */
225 ctrl = TIMER_CTRL_ONESHOT;
226 ctrl |= TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE;
227 break;
228 case CLOCK_EVT_MODE_UNUSED:
229 case CLOCK_EVT_MODE_SHUTDOWN:
230 default:
231 ctrl = 0;
232 }
233
234 writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
235}
236
237static int timer_set_next_event(unsigned long evt,
238 struct clock_event_device *unused)
239{
240 unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
241
242 writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
243 writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
244
245 return 0;
246}
247
248static struct clock_event_device timer0_clockevent = {
249 .name = "timer0",
250 .shift = 32,
251 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
252 .set_mode = timer_set_mode,
253 .set_next_event = timer_set_next_event,
254};
255
256/*
257 * IRQ handler for the timer
258 */
259static irqreturn_t bcmring_timer_interrupt(int irq, void *dev_id)
260{
261 struct clock_event_device *evt = &timer0_clockevent;
262
263 writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
264
265 evt->event_handler(evt);
266
267 return IRQ_HANDLED;
268}
269
270static struct irqaction bcmring_timer_irq = {
271 .name = "bcmring Timer Tick",
272 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
273 .handler = bcmring_timer_interrupt,
274};
275
276static cycle_t bcmring_get_cycles_timer1(void)
277{
278 return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
279}
280
281static cycle_t bcmring_get_cycles_timer3(void)
282{
283 return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
284}
285
286static struct clocksource clocksource_bcmring_timer1 = {
287 .name = "timer1",
288 .rating = 200,
289 .read = bcmring_get_cycles_timer1,
290 .mask = CLOCKSOURCE_MASK(32),
291 .shift = 20,
292 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
293};
294
295static struct clocksource clocksource_bcmring_timer3 = {
296 .name = "timer3",
297 .rating = 100,
298 .read = bcmring_get_cycles_timer3,
299 .mask = CLOCKSOURCE_MASK(32),
300 .shift = 20,
301 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
302};
303
304static int __init bcmring_clocksource_init(void)
305{
306 /* setup timer1 as free-running clocksource */
307 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
308 writel(0xffffffff, TIMER1_VA_BASE + TIMER_LOAD);
309 writel(0xffffffff, TIMER1_VA_BASE + TIMER_VALUE);
310 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
311 TIMER1_VA_BASE + TIMER_CTRL);
312
313 clocksource_bcmring_timer1.mult =
314 clocksource_khz2mult(TIMER1_FREQUENCY_MHZ * 1000,
315 clocksource_bcmring_timer1.shift);
316 clocksource_register(&clocksource_bcmring_timer1);
317
318 /* setup timer3 as free-running clocksource */
319 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
320 writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
321 writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
322 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
323 TIMER3_VA_BASE + TIMER_CTRL);
324
325 clocksource_bcmring_timer3.mult =
326 clocksource_khz2mult(TIMER3_FREQUENCY_KHZ,
327 clocksource_bcmring_timer3.shift);
328 clocksource_register(&clocksource_bcmring_timer3);
329
330 return 0;
331}
332
333/*
334 * Set up timer interrupt, and return the current time in seconds.
335 */
336void __init bcmring_init_timer(void)
337{
338 printk(KERN_INFO "bcmring_init_timer\n");
339 /*
340 * Initialise to a known state (all timers off)
341 */
342 writel(0, TIMER0_VA_BASE + TIMER_CTRL);
343 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
344 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
345 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
346
347 /*
348 * Make irqs happen for the system timer
349 */
350 setup_irq(IRQ_TIMER0, &bcmring_timer_irq);
351
352 bcmring_clocksource_init();
353
354 timer0_clockevent.mult =
355 div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
356 timer0_clockevent.max_delta_ns =
357 clockevent_delta2ns(0xffffffff, &timer0_clockevent);
358 timer0_clockevent.min_delta_ns =
359 clockevent_delta2ns(0xf, &timer0_clockevent);
360
361 timer0_clockevent.cpumask = cpumask_of(0);
362 clockevents_register_device(&timer0_clockevent);
363}
364
365struct sys_timer bcmring_timer = {
366 .init = bcmring_init_timer,
367};
diff --git a/arch/arm/mach-bcmring/core.h b/arch/arm/mach-bcmring/core.h
new file mode 100644
index 000000000000..b197ba48e36e
--- /dev/null
+++ b/arch/arm/mach-bcmring/core.h
@@ -0,0 +1,30 @@
1/*
2 * linux/arch/arm/mach-versatile/core.h
3 *
4 * Copyright (C) 2004 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21/* Portions copyright Broadcom 2008 */
22#ifndef __ASM_ARCH_BCMRING_H
23#define __ASM_ARCH_BCMRING_H
24
25void __init bcmring_amba_init(void);
26void __init bcmring_map_io(void);
27void __init bcmring_init_irq(void);
28
29extern struct sys_timer bcmring_timer;
30#endif
diff --git a/arch/arm/mach-bcmring/csp/Makefile b/arch/arm/mach-bcmring/csp/Makefile
new file mode 100644
index 000000000000..648c0377530e
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/Makefile
@@ -0,0 +1,3 @@
1obj-y += dmac/
2obj-y += tmr/
3obj-y += chipc/
diff --git a/arch/arm/mach-bcmring/csp/chipc/Makefile b/arch/arm/mach-bcmring/csp/chipc/Makefile
new file mode 100644
index 000000000000..673952768ee5
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/Makefile
@@ -0,0 +1 @@
obj-y += chipcHw.o chipcHw_str.o chipcHw_reset.o chipcHw_init.o
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c
new file mode 100644
index 000000000000..b3a61d860c65
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c
@@ -0,0 +1,776 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file chipcHw.c
18*
19* @brief Low level Various CHIP clock controlling routines
20*
21* @note
22*
23* These routines provide basic clock controlling functionality only.
24*/
25/****************************************************************************/
26
27/* ---- Include Files ---------------------------------------------------- */
28
29#include <csp/errno.h>
30#include <csp/stdint.h>
31#include <csp/module.h>
32
33#include <mach/csp/chipcHw_def.h>
34#include <mach/csp/chipcHw_inline.h>
35
36#include <csp/reg.h>
37#include <csp/delay.h>
38
39/* ---- Private Constants and Types --------------------------------------- */
40
41/* VPM alignment algorithm uses this */
42#define MAX_PHASE_ADJUST_COUNT 0xFFFF /* Max number of times allowed to adjust the phase */
43#define MAX_PHASE_ALIGN_ATTEMPTS 10 /* Max number of attempt to align the phase */
44
45/* Local definition of clock type */
46#define PLL_CLOCK 1 /* PLL Clock */
47#define NON_PLL_CLOCK 2 /* Divider clock */
48
49static int chipcHw_divide(int num, int denom)
50 __attribute__ ((section(".aramtext")));
51
52/****************************************************************************/
53/**
54* @brief Set clock fequency for miscellaneous configurable clocks
55*
56* This function sets clock frequency
57*
58* @return Configured clock frequency in hertz
59*
60*/
61/****************************************************************************/
62chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
63 ) {
64 volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
65 volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
66 volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
67 uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */
68 uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */
69 uint32_t dependentClockType = 0;
70 uint32_t vcoHz = 0;
71
72 /* Get VCO frequencies */
73 if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
74 uint64_t adjustFreq = 0;
75
76 vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
77 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
78 ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
79 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
80
81 /* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
82 adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
83 (uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
84 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
85 vcoFreqPll1Hz += (uint32_t) adjustFreq;
86 } else {
87 vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
88 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
89 ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
90 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
91 }
92 vcoFreqPll2Hz =
93 chipcHw_XTAL_FREQ_Hz *
94 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
95 ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
96 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
97
98 switch (clock) {
99 case chipcHw_CLOCK_DDR:
100 pPLLReg = &pChipcHw->DDRClock;
101 vcoHz = vcoFreqPll1Hz;
102 break;
103 case chipcHw_CLOCK_ARM:
104 pPLLReg = &pChipcHw->ARMClock;
105 vcoHz = vcoFreqPll1Hz;
106 break;
107 case chipcHw_CLOCK_ESW:
108 pPLLReg = &pChipcHw->ESWClock;
109 vcoHz = vcoFreqPll1Hz;
110 break;
111 case chipcHw_CLOCK_VPM:
112 pPLLReg = &pChipcHw->VPMClock;
113 vcoHz = vcoFreqPll1Hz;
114 break;
115 case chipcHw_CLOCK_ESW125:
116 pPLLReg = &pChipcHw->ESW125Clock;
117 vcoHz = vcoFreqPll1Hz;
118 break;
119 case chipcHw_CLOCK_UART:
120 pPLLReg = &pChipcHw->UARTClock;
121 vcoHz = vcoFreqPll1Hz;
122 break;
123 case chipcHw_CLOCK_SDIO0:
124 pPLLReg = &pChipcHw->SDIO0Clock;
125 vcoHz = vcoFreqPll1Hz;
126 break;
127 case chipcHw_CLOCK_SDIO1:
128 pPLLReg = &pChipcHw->SDIO1Clock;
129 vcoHz = vcoFreqPll1Hz;
130 break;
131 case chipcHw_CLOCK_SPI:
132 pPLLReg = &pChipcHw->SPIClock;
133 vcoHz = vcoFreqPll1Hz;
134 break;
135 case chipcHw_CLOCK_ETM:
136 pPLLReg = &pChipcHw->ETMClock;
137 vcoHz = vcoFreqPll1Hz;
138 break;
139 case chipcHw_CLOCK_USB:
140 pPLLReg = &pChipcHw->USBClock;
141 vcoHz = vcoFreqPll2Hz;
142 break;
143 case chipcHw_CLOCK_LCD:
144 pPLLReg = &pChipcHw->LCDClock;
145 vcoHz = vcoFreqPll2Hz;
146 break;
147 case chipcHw_CLOCK_APM:
148 pPLLReg = &pChipcHw->APMClock;
149 vcoHz = vcoFreqPll2Hz;
150 break;
151 case chipcHw_CLOCK_BUS:
152 pClockCtrl = &pChipcHw->ACLKClock;
153 pDependentClock = &pChipcHw->ARMClock;
154 vcoHz = vcoFreqPll1Hz;
155 dependentClockType = PLL_CLOCK;
156 break;
157 case chipcHw_CLOCK_OTP:
158 pClockCtrl = &pChipcHw->OTPClock;
159 break;
160 case chipcHw_CLOCK_I2C:
161 pClockCtrl = &pChipcHw->I2CClock;
162 break;
163 case chipcHw_CLOCK_I2S0:
164 pClockCtrl = &pChipcHw->I2S0Clock;
165 break;
166 case chipcHw_CLOCK_RTBUS:
167 pClockCtrl = &pChipcHw->RTBUSClock;
168 pDependentClock = &pChipcHw->ACLKClock;
169 dependentClockType = NON_PLL_CLOCK;
170 break;
171 case chipcHw_CLOCK_APM100:
172 pClockCtrl = &pChipcHw->APM100Clock;
173 pDependentClock = &pChipcHw->APMClock;
174 vcoHz = vcoFreqPll2Hz;
175 dependentClockType = PLL_CLOCK;
176 break;
177 case chipcHw_CLOCK_TSC:
178 pClockCtrl = &pChipcHw->TSCClock;
179 break;
180 case chipcHw_CLOCK_LED:
181 pClockCtrl = &pChipcHw->LEDClock;
182 break;
183 case chipcHw_CLOCK_I2S1:
184 pClockCtrl = &pChipcHw->I2S1Clock;
185 break;
186 }
187
188 if (pPLLReg) {
189 /* Obtain PLL clock frequency */
190 if (*pPLLReg & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
191 /* Return crystal clock frequency when bypassed */
192 return chipcHw_XTAL_FREQ_Hz;
193 } else if (clock == chipcHw_CLOCK_DDR) {
194 /* DDR frequency is configured in PLLDivider register */
195 return chipcHw_divide (vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
196 } else {
197 /* From chip revision number B0, LCD clock is internally divided by 2 */
198 if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
199 vcoHz >>= 1;
200 }
201 /* Obtain PLL clock frequency using VCO dividers */
202 return chipcHw_divide(vcoHz, ((*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
203 }
204 } else if (pClockCtrl) {
205 /* Obtain divider clock frequency */
206 uint32_t div;
207 uint32_t freq = 0;
208
209 if (*pClockCtrl & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
210 /* Return crystal clock frequency when bypassed */
211 return chipcHw_XTAL_FREQ_Hz;
212 } else if (pDependentClock) {
213 /* Identify the dependent clock frequency */
214 switch (dependentClockType) {
215 case PLL_CLOCK:
216 if (*pDependentClock & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
217 /* Use crystal clock frequency when dependent PLL clock is bypassed */
218 freq = chipcHw_XTAL_FREQ_Hz;
219 } else {
220 /* Obtain PLL clock frequency using VCO dividers */
221 div = *pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK;
222 freq = div ? chipcHw_divide(vcoHz, div) : 0;
223 }
224 break;
225 case NON_PLL_CLOCK:
226 if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
227 freq = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
228 } else {
229 if (*pDependentClock & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
230 /* Use crystal clock frequency when dependent divider clock is bypassed */
231 freq = chipcHw_XTAL_FREQ_Hz;
232 } else {
233 /* Obtain divider clock frequency using XTAL dividers */
234 div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
235 freq = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, (div ? div : 256));
236 }
237 }
238 break;
239 }
240 } else {
241 /* Dependent on crystal clock */
242 freq = chipcHw_XTAL_FREQ_Hz;
243 }
244
245 div = *pClockCtrl & chipcHw_REG_DIV_CLOCK_DIV_MASK;
246 return chipcHw_divide(freq, (div ? div : 256));
247 }
248 return 0;
249}
250
251/****************************************************************************/
252/**
253* @brief Set clock fequency for miscellaneous configurable clocks
254*
255* This function sets clock frequency
256*
257* @return Configured clock frequency in Hz
258*
259*/
260/****************************************************************************/
261chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */
262 uint32_t freq /* [ IN ] Clock frequency in Hz */
263 ) {
264 volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
265 volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
266 volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
267 uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */
268 uint32_t desVcoFreqPll1Hz = 0; /* Desired VCO frequency for PLL1 in Hz */
269 uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */
270 uint32_t dependentClockType = 0;
271 uint32_t vcoHz = 0;
272 uint32_t desVcoHz = 0;
273
274 /* Get VCO frequencies */
275 if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
276 uint64_t adjustFreq = 0;
277
278 vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
279 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
280 ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
281 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
282
283 /* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
284 adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
285 (uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
286 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
287 vcoFreqPll1Hz += (uint32_t) adjustFreq;
288
289 /* Desired VCO frequency */
290 desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
291 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
292 (((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
293 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) + 1);
294 } else {
295 vcoFreqPll1Hz = desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
296 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
297 ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
298 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
299 }
300 vcoFreqPll2Hz = chipcHw_XTAL_FREQ_Hz * chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
301 ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
302 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
303
304 switch (clock) {
305 case chipcHw_CLOCK_DDR:
306 /* Configure the DDR_ctrl:BUS ratio settings */
307 {
308 REG_LOCAL_IRQ_SAVE;
309 /* Dvide DDR_phy by two to obtain DDR_ctrl clock */
310 pChipcHw->DDRClock = (pChipcHw->DDRClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((((freq / 2) / chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
311 << chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
312 REG_LOCAL_IRQ_RESTORE;
313 }
314 pPLLReg = &pChipcHw->DDRClock;
315 vcoHz = vcoFreqPll1Hz;
316 desVcoHz = desVcoFreqPll1Hz;
317 break;
318 case chipcHw_CLOCK_ARM:
319 pPLLReg = &pChipcHw->ARMClock;
320 vcoHz = vcoFreqPll1Hz;
321 desVcoHz = desVcoFreqPll1Hz;
322 break;
323 case chipcHw_CLOCK_ESW:
324 pPLLReg = &pChipcHw->ESWClock;
325 vcoHz = vcoFreqPll1Hz;
326 desVcoHz = desVcoFreqPll1Hz;
327 break;
328 case chipcHw_CLOCK_VPM:
329 /* Configure the VPM:BUS ratio settings */
330 {
331 REG_LOCAL_IRQ_SAVE;
332 pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((chipcHw_divide (freq, chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
333 << chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
334 REG_LOCAL_IRQ_RESTORE;
335 }
336 pPLLReg = &pChipcHw->VPMClock;
337 vcoHz = vcoFreqPll1Hz;
338 desVcoHz = desVcoFreqPll1Hz;
339 break;
340 case chipcHw_CLOCK_ESW125:
341 pPLLReg = &pChipcHw->ESW125Clock;
342 vcoHz = vcoFreqPll1Hz;
343 desVcoHz = desVcoFreqPll1Hz;
344 break;
345 case chipcHw_CLOCK_UART:
346 pPLLReg = &pChipcHw->UARTClock;
347 vcoHz = vcoFreqPll1Hz;
348 desVcoHz = desVcoFreqPll1Hz;
349 break;
350 case chipcHw_CLOCK_SDIO0:
351 pPLLReg = &pChipcHw->SDIO0Clock;
352 vcoHz = vcoFreqPll1Hz;
353 desVcoHz = desVcoFreqPll1Hz;
354 break;
355 case chipcHw_CLOCK_SDIO1:
356 pPLLReg = &pChipcHw->SDIO1Clock;
357 vcoHz = vcoFreqPll1Hz;
358 desVcoHz = desVcoFreqPll1Hz;
359 break;
360 case chipcHw_CLOCK_SPI:
361 pPLLReg = &pChipcHw->SPIClock;
362 vcoHz = vcoFreqPll1Hz;
363 desVcoHz = desVcoFreqPll1Hz;
364 break;
365 case chipcHw_CLOCK_ETM:
366 pPLLReg = &pChipcHw->ETMClock;
367 vcoHz = vcoFreqPll1Hz;
368 desVcoHz = desVcoFreqPll1Hz;
369 break;
370 case chipcHw_CLOCK_USB:
371 pPLLReg = &pChipcHw->USBClock;
372 vcoHz = vcoFreqPll2Hz;
373 desVcoHz = vcoFreqPll2Hz;
374 break;
375 case chipcHw_CLOCK_LCD:
376 pPLLReg = &pChipcHw->LCDClock;
377 vcoHz = vcoFreqPll2Hz;
378 desVcoHz = vcoFreqPll2Hz;
379 break;
380 case chipcHw_CLOCK_APM:
381 pPLLReg = &pChipcHw->APMClock;
382 vcoHz = vcoFreqPll2Hz;
383 desVcoHz = vcoFreqPll2Hz;
384 break;
385 case chipcHw_CLOCK_BUS:
386 pClockCtrl = &pChipcHw->ACLKClock;
387 pDependentClock = &pChipcHw->ARMClock;
388 vcoHz = vcoFreqPll1Hz;
389 desVcoHz = desVcoFreqPll1Hz;
390 dependentClockType = PLL_CLOCK;
391 break;
392 case chipcHw_CLOCK_OTP:
393 pClockCtrl = &pChipcHw->OTPClock;
394 break;
395 case chipcHw_CLOCK_I2C:
396 pClockCtrl = &pChipcHw->I2CClock;
397 break;
398 case chipcHw_CLOCK_I2S0:
399 pClockCtrl = &pChipcHw->I2S0Clock;
400 break;
401 case chipcHw_CLOCK_RTBUS:
402 pClockCtrl = &pChipcHw->RTBUSClock;
403 pDependentClock = &pChipcHw->ACLKClock;
404 dependentClockType = NON_PLL_CLOCK;
405 break;
406 case chipcHw_CLOCK_APM100:
407 pClockCtrl = &pChipcHw->APM100Clock;
408 pDependentClock = &pChipcHw->APMClock;
409 vcoHz = vcoFreqPll2Hz;
410 desVcoHz = vcoFreqPll2Hz;
411 dependentClockType = PLL_CLOCK;
412 break;
413 case chipcHw_CLOCK_TSC:
414 pClockCtrl = &pChipcHw->TSCClock;
415 break;
416 case chipcHw_CLOCK_LED:
417 pClockCtrl = &pChipcHw->LEDClock;
418 break;
419 case chipcHw_CLOCK_I2S1:
420 pClockCtrl = &pChipcHw->I2S1Clock;
421 break;
422 }
423
424 if (pPLLReg) {
425 /* Select XTAL as bypass source */
426 reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_SOURCE_GPIO);
427 reg32_modify_or(pPLLReg, chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
428 /* For DDR settings use only the PLL divider clock */
429 if (pPLLReg == &pChipcHw->DDRClock) {
430 /* Set M1DIV for PLL1, which controls the DDR clock */
431 reg32_write(&pChipcHw->PLLDivider, (pChipcHw->PLLDivider & 0x00FFFFFF) | ((chipcHw_REG_PLL_DIVIDER_MDIV (desVcoHz, freq)) << 24));
432 /* Calculate expected frequency */
433 freq = chipcHw_divide(vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
434 } else {
435 /* From chip revision number B0, LCD clock is internally divided by 2 */
436 if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
437 desVcoHz >>= 1;
438 vcoHz >>= 1;
439 }
440 /* Set MDIV to change the frequency */
441 reg32_modify_and(pPLLReg, ~(chipcHw_REG_PLL_CLOCK_MDIV_MASK));
442 reg32_modify_or(pPLLReg, chipcHw_REG_PLL_DIVIDER_MDIV(desVcoHz, freq));
443 /* Calculate expected frequency */
444 freq = chipcHw_divide(vcoHz, ((*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
445 }
446 /* Wait for for atleast 200ns as per the protocol to change frequency */
447 udelay(1);
448 /* Do not bypass */
449 reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
450 /* Return the configured frequency */
451 return freq;
452 } else if (pClockCtrl) {
453 uint32_t divider = 0;
454
455 /* Divider clock should not be bypassed */
456 reg32_modify_and(pClockCtrl,
457 ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
458
459 /* Identify the clock source */
460 if (pDependentClock) {
461 switch (dependentClockType) {
462 case PLL_CLOCK:
463 divider = chipcHw_divide(chipcHw_divide (desVcoHz, (*pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK)), freq);
464 break;
465 case NON_PLL_CLOCK:
466 {
467 uint32_t sourceClock = 0;
468
469 if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
470 sourceClock = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
471 } else {
472 uint32_t div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
473 sourceClock = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, ((div) ? div : 256));
474 }
475 divider = chipcHw_divide(sourceClock, freq);
476 }
477 break;
478 }
479 } else {
480 divider = chipcHw_divide(chipcHw_XTAL_FREQ_Hz, freq);
481 }
482
483 if (divider) {
484 REG_LOCAL_IRQ_SAVE;
485 /* Set the divider to obtain the required frequency */
486 *pClockCtrl = (*pClockCtrl & (~chipcHw_REG_DIV_CLOCK_DIV_MASK)) | (((divider > 256) ? chipcHw_REG_DIV_CLOCK_DIV_256 : divider) & chipcHw_REG_DIV_CLOCK_DIV_MASK);
487 REG_LOCAL_IRQ_RESTORE;
488 return freq;
489 }
490 }
491
492 return 0;
493}
494
495EXPORT_SYMBOL(chipcHw_setClockFrequency);
496
497/****************************************************************************/
498/**
499* @brief Set VPM clock in sync with BUS clock for Chip Rev #A0
500*
501* This function does the phase adjustment between VPM and BUS clock
502*
503* @return >= 0 : On success (# of adjustment required)
504* -1 : On failure
505*
506*/
507/****************************************************************************/
508static int vpmPhaseAlignA0(void)
509{
510 uint32_t phaseControl;
511 uint32_t phaseValue;
512 uint32_t prevPhaseComp;
513 int iter = 0;
514 int adjustCount = 0;
515 int count = 0;
516
517 for (iter = 0; (iter < MAX_PHASE_ALIGN_ATTEMPTS) && (adjustCount < MAX_PHASE_ADJUST_COUNT); iter++) {
518 phaseControl = (pChipcHw->VPMClock & chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT;
519 phaseValue = 0;
520 prevPhaseComp = 0;
521
522 /* Step 1: Look for falling PH_COMP transition */
523
524 /* Read the contents of VPM Clock resgister */
525 phaseValue = pChipcHw->VPMClock;
526 do {
527 /* Store previous value of phase comparator */
528 prevPhaseComp = phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP;
529 /* Change the value of PH_CTRL. */
530 reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
531 /* Wait atleast 20 ns */
532 udelay(1);
533 /* Toggle the LOAD_CH after phase control is written. */
534 pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
535 /* Read the contents of VPM Clock resgister. */
536 phaseValue = pChipcHw->VPMClock;
537
538 if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
539 phaseControl = (0x3F & (phaseControl - 1));
540 } else {
541 /* Increment to the Phase count value for next write, if Phase is not stable. */
542 phaseControl = (0x3F & (phaseControl + 1));
543 }
544 /* Count number of adjustment made */
545 adjustCount++;
546 } while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || /* Look for a transition */
547 ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && /* Look for a falling edge */
548 (adjustCount < MAX_PHASE_ADJUST_COUNT) /* Do not exceed the limit while trying */
549 );
550
551 if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
552 /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
553 return -1;
554 }
555
556 /* Step 2: Keep moving forward to make sure falling PH_COMP transition was valid */
557
558 for (count = 0; (count < 5) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
559 phaseControl = (0x3F & (phaseControl + 1));
560 reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
561 /* Wait atleast 20 ns */
562 udelay(1);
563 /* Toggle the LOAD_CH after phase control is written. */
564 pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
565 phaseValue = pChipcHw->VPMClock;
566 /* Count number of adjustment made */
567 adjustCount++;
568 }
569
570 if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
571 /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
572 return -1;
573 }
574
575 if (count != 5) {
576 /* Detected false transition */
577 continue;
578 }
579
580 /* Step 3: Keep moving backward to make sure falling PH_COMP transition was stable */
581
582 for (count = 0; (count < 3) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
583 phaseControl = (0x3F & (phaseControl - 1));
584 reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
585 /* Wait atleast 20 ns */
586 udelay(1);
587 /* Toggle the LOAD_CH after phase control is written. */
588 pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
589 phaseValue = pChipcHw->VPMClock;
590 /* Count number of adjustment made */
591 adjustCount++;
592 }
593
594 if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
595 /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
596 return -1;
597 }
598
599 if (count != 3) {
600 /* Detected noisy transition */
601 continue;
602 }
603
604 /* Step 4: Keep moving backward before the original transition took place. */
605
606 for (count = 0; (count < 5); count++) {
607 phaseControl = (0x3F & (phaseControl - 1));
608 reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
609 /* Wait atleast 20 ns */
610 udelay(1);
611 /* Toggle the LOAD_CH after phase control is written. */
612 pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
613 phaseValue = pChipcHw->VPMClock;
614 /* Count number of adjustment made */
615 adjustCount++;
616 }
617
618 if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
619 /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
620 return -1;
621 }
622
623 if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0) {
624 /* Detected false transition */
625 continue;
626 }
627
628 /* Step 5: Re discover the valid transition */
629
630 do {
631 /* Store previous value of phase comparator */
632 prevPhaseComp = phaseValue;
633 /* Change the value of PH_CTRL. */
634 reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
635 /* Wait atleast 20 ns */
636 udelay(1);
637 /* Toggle the LOAD_CH after phase control is written. */
638 pChipcHw->VPMClock ^=
639 chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
640 /* Read the contents of VPM Clock resgister. */
641 phaseValue = pChipcHw->VPMClock;
642
643 if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
644 phaseControl = (0x3F & (phaseControl - 1));
645 } else {
646 /* Increment to the Phase count value for next write, if Phase is not stable. */
647 phaseControl = (0x3F & (phaseControl + 1));
648 }
649
650 /* Count number of adjustment made */
651 adjustCount++;
652 } while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && (adjustCount < MAX_PHASE_ADJUST_COUNT));
653
654 if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
655 /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
656 return -1;
657 } else {
658 /* Valid phase must have detected */
659 break;
660 }
661 }
662
663 /* For VPM Phase should be perfectly aligned. */
664 phaseControl = (((pChipcHw->VPMClock >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT) - 1) & 0x3F);
665 {
666 REG_LOCAL_IRQ_SAVE;
667
668 pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT);
669 /* Load new phase value */
670 pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
671
672 REG_LOCAL_IRQ_RESTORE;
673 }
674 /* Return the status */
675 return (int)adjustCount;
676}
677
678/****************************************************************************/
679/**
680* @brief Set VPM clock in sync with BUS clock
681*
682* This function does the phase adjustment between VPM and BUS clock
683*
684* @return >= 0 : On success (# of adjustment required)
685* -1 : On failure
686*
687*/
688/****************************************************************************/
689int chipcHw_vpmPhaseAlign(void)
690{
691
692 if (chipcHw_getChipRevisionNumber() == chipcHw_REV_NUMBER_A0) {
693 return vpmPhaseAlignA0();
694 } else {
695 uint32_t phaseControl = chipcHw_getVpmPhaseControl();
696 uint32_t phaseValue = 0;
697 int adjustCount = 0;
698
699 /* Disable VPM access */
700 pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
701 /* Disable HW VPM phase alignment */
702 chipcHw_vpmHwPhaseAlignDisable();
703 /* Enable SW VPM phase alignment */
704 chipcHw_vpmSwPhaseAlignEnable();
705 /* Adjust VPM phase */
706 while (adjustCount < MAX_PHASE_ADJUST_COUNT) {
707 phaseValue = chipcHw_getVpmHwPhaseAlignStatus();
708
709 /* Adjust phase control value */
710 if (phaseValue > 0xF) {
711 /* Increment phase control value */
712 phaseControl++;
713 } else if (phaseValue < 0xF) {
714 /* Decrement phase control value */
715 phaseControl--;
716 } else {
717 /* Enable VPM access */
718 pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
719 /* Return adjust count */
720 return adjustCount;
721 }
722 /* Change the value of PH_CTRL. */
723 reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
724 /* Wait atleast 20 ns */
725 udelay(1);
726 /* Toggle the LOAD_CH after phase control is written. */
727 pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
728 /* Count adjustment */
729 adjustCount++;
730 }
731 }
732
733 /* Disable VPM access */
734 pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
735 return -1;
736}
737
738/****************************************************************************/
739/**
740* @brief Local Divide function
741*
742* This function does the divide
743*
744* @return divide value
745*
746*/
747/****************************************************************************/
748static int chipcHw_divide(int num, int denom)
749{
750 int r;
751 int t = 1;
752
753 /* Shift denom and t up to the largest value to optimize algorithm */
754 /* t contains the units of each divide */
755 while ((denom & 0x40000000) == 0) { /* fails if denom=0 */
756 denom = denom << 1;
757 t = t << 1;
758 }
759
760 /* Intialize the result */
761 r = 0;
762
763 do {
764 /* Determine if there exists a positive remainder */
765 if ((num - denom) >= 0) {
766 /* Accumlate t to the result and calculate a new remainder */
767 num = num - denom;
768 r = r + t;
769 }
770 /* Continue to shift denom and shift t down to 0 */
771 denom = denom >> 1;
772 t = t >> 1;
773 } while (t != 0);
774
775 return r;
776}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
new file mode 100644
index 000000000000..367df75d4bb3
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
@@ -0,0 +1,293 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file chipcHw_init.c
18*
19* @brief Low level CHIPC PLL configuration functions
20*
21* @note
22*
23* These routines provide basic PLL controlling functionality only.
24*/
25/****************************************************************************/
26
27/* ---- Include Files ---------------------------------------------------- */
28
29#include <csp/errno.h>
30#include <csp/stdint.h>
31#include <csp/module.h>
32
33#include <mach/csp/chipcHw_def.h>
34#include <mach/csp/chipcHw_inline.h>
35
36#include <csp/reg.h>
37#include <csp/delay.h>
38/* ---- Private Constants and Types --------------------------------------- */
39
40/*
41 Calculation for NDIV_i to obtain VCO frequency
42 -----------------------------------------------
43
44 Freq_vco = Freq_ref * (P2 / P1) * (PLL_NDIV_i + PLL_NDIV_f)
45 for Freq_vco = VCO_FREQ_MHz
46 Freq_ref = chipcHw_XTAL_FREQ_Hz
47 PLL_P1 = PLL_P2 = 1
48 and
49 PLL_NDIV_f = 0
50
51 We get:
52 PLL_NDIV_i = Freq_vco / Freq_ref = VCO_FREQ_MHz / chipcHw_XTAL_FREQ_Hz
53
54 Calculation for PLL MDIV to obtain frequency Freq_x for channel x
55 -----------------------------------------------------------------
56 Freq_x = chipcHw_XTAL_FREQ_Hz * PLL_NDIV_i / PLL_MDIV_x = VCO_FREQ_MHz / PLL_MDIV_x
57
58 PLL_MDIV_x = VCO_FREQ_MHz / Freq_x
59*/
60
61/* ---- Private Variables ------------------------------------------------- */
62/****************************************************************************/
63/**
64* @brief Initializes the PLL2
65*
66* This function initializes the PLL2
67*
68*/
69/****************************************************************************/
70void chipcHw_pll2Enable(uint32_t vcoFreqHz)
71{
72 uint32_t pllPreDivider2 = 0;
73
74 {
75 REG_LOCAL_IRQ_SAVE;
76 pChipcHw->PLLConfig2 =
77 chipcHw_REG_PLL_CONFIG_D_RESET |
78 chipcHw_REG_PLL_CONFIG_A_RESET;
79
80 pllPreDivider2 = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
81 chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
82 (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
83 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
84 (chipcHw_REG_PLL_PREDIVIDER_P1 <<
85 chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
86 (chipcHw_REG_PLL_PREDIVIDER_P2 <<
87 chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
88
89 /* Enable CHIPC registers to control the PLL */
90 pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
91
92 /* Set pre divider to get desired VCO frequency */
93 pChipcHw->PLLPreDivider2 = pllPreDivider2;
94 /* Set NDIV Frac */
95 pChipcHw->PLLDivider2 = chipcHw_REG_PLL_DIVIDER_NDIV_f;
96
97 /* This has to be removed once the default values are fixed for PLL2. */
98 pChipcHw->PLLControl12 = 0x38000700;
99 pChipcHw->PLLControl22 = 0x00000015;
100
101 /* Reset PLL2 */
102 if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
103 pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
104 chipcHw_REG_PLL_CONFIG_A_RESET |
105 chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
106 chipcHw_REG_PLL_CONFIG_POWER_DOWN;
107 } else {
108 pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
109 chipcHw_REG_PLL_CONFIG_A_RESET |
110 chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
111 chipcHw_REG_PLL_CONFIG_POWER_DOWN;
112 }
113 REG_LOCAL_IRQ_RESTORE;
114 }
115
116 /* Insert certain amount of delay before deasserting ARESET. */
117 udelay(1);
118
119 {
120 REG_LOCAL_IRQ_SAVE;
121 /* Remove analog reset and Power on the PLL */
122 pChipcHw->PLLConfig2 &=
123 ~(chipcHw_REG_PLL_CONFIG_A_RESET |
124 chipcHw_REG_PLL_CONFIG_POWER_DOWN);
125
126 REG_LOCAL_IRQ_RESTORE;
127
128 }
129
130 /* Wait until PLL is locked */
131 while (!(pChipcHw->PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
132 ;
133
134 {
135 REG_LOCAL_IRQ_SAVE;
136 /* Remove digital reset */
137 pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
138
139 REG_LOCAL_IRQ_RESTORE;
140 }
141}
142
143EXPORT_SYMBOL(chipcHw_pll2Enable);
144
145/****************************************************************************/
146/**
147* @brief Initializes the PLL1
148*
149* This function initializes the PLL1
150*
151*/
152/****************************************************************************/
153void chipcHw_pll1Enable(uint32_t vcoFreqHz, chipcHw_SPREAD_SPECTRUM_e ssSupport)
154{
155 uint32_t pllPreDivider = 0;
156
157 {
158 REG_LOCAL_IRQ_SAVE;
159
160 pChipcHw->PLLConfig =
161 chipcHw_REG_PLL_CONFIG_D_RESET |
162 chipcHw_REG_PLL_CONFIG_A_RESET;
163 /* Setting VCO frequency */
164 if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
165 pllPreDivider =
166 chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 |
167 ((chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) -
168 1) << chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
169 (chipcHw_REG_PLL_PREDIVIDER_P1 <<
170 chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
171 (chipcHw_REG_PLL_PREDIVIDER_P2 <<
172 chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
173 } else {
174 pllPreDivider = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
175 chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
176 (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
177 chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
178 (chipcHw_REG_PLL_PREDIVIDER_P1 <<
179 chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
180 (chipcHw_REG_PLL_PREDIVIDER_P2 <<
181 chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
182 }
183
184 /* Enable CHIPC registers to control the PLL */
185 pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
186
187 /* Set pre divider to get desired VCO frequency */
188 pChipcHw->PLLPreDivider = pllPreDivider;
189 /* Set NDIV Frac */
190 if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
191 pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
192 chipcHw_REG_PLL_DIVIDER_NDIV_f_SS;
193 } else {
194 pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
195 chipcHw_REG_PLL_DIVIDER_NDIV_f;
196 }
197
198 /* Reset PLL1 */
199 if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
200 pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
201 chipcHw_REG_PLL_CONFIG_A_RESET |
202 chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
203 chipcHw_REG_PLL_CONFIG_POWER_DOWN;
204 } else {
205 pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
206 chipcHw_REG_PLL_CONFIG_A_RESET |
207 chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
208 chipcHw_REG_PLL_CONFIG_POWER_DOWN;
209 }
210
211 REG_LOCAL_IRQ_RESTORE;
212
213 /* Insert certain amount of delay before deasserting ARESET. */
214 udelay(1);
215
216 {
217 REG_LOCAL_IRQ_SAVE;
218 /* Remove analog reset and Power on the PLL */
219 pChipcHw->PLLConfig &=
220 ~(chipcHw_REG_PLL_CONFIG_A_RESET |
221 chipcHw_REG_PLL_CONFIG_POWER_DOWN);
222 REG_LOCAL_IRQ_RESTORE;
223 }
224
225 /* Wait until PLL is locked */
226 while (!(pChipcHw->PLLStatus & chipcHw_REG_PLL_STATUS_LOCKED)
227 || !(pChipcHw->
228 PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
229 ;
230
231 /* Remove digital reset */
232 {
233 REG_LOCAL_IRQ_SAVE;
234 pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
235 REG_LOCAL_IRQ_RESTORE;
236 }
237 }
238}
239
240EXPORT_SYMBOL(chipcHw_pll1Enable);
241
242/****************************************************************************/
243/**
244* @brief Initializes the chipc module
245*
246* This function initializes the PLLs and core system clocks
247*
248*/
249/****************************************************************************/
250
251void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */
252 ) {
253#if !(defined(__KERNEL__) && !defined(STANDALONE))
254 delay_init();
255#endif
256
257 /* Do not program PLL, when warm reset */
258 if (!(chipcHw_getStickyBits() & chipcHw_REG_STICKY_CHIP_WARM_RESET)) {
259 chipcHw_pll1Enable(initParam->pllVcoFreqHz,
260 initParam->ssSupport);
261 chipcHw_pll2Enable(initParam->pll2VcoFreqHz);
262 } else {
263 /* Clear sticky bits */
264 chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_WARM_RESET);
265 }
266 /* Clear sticky bits */
267 chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_SOFT_RESET);
268
269 /* Before configuring the ARM clock, atleast we need to make sure BUS clock maintains the proper ratio with ARM clock */
270 pChipcHw->ACLKClock =
271 (pChipcHw->
272 ACLKClock & ~chipcHw_REG_ACLKClock_CLK_DIV_MASK) | (initParam->
273 armBusRatio &
274 chipcHw_REG_ACLKClock_CLK_DIV_MASK);
275
276 /* Set various core component frequencies. The order in which this is done is important for some. */
277 /* The RTBUS (DDR PHY) is derived from the BUS, and the BUS from the ARM, and VPM needs to know BUS */
278 /* frequency to find its ratio with the BUS. Hence we must set the ARM first, followed by the BUS, */
279 /* then VPM and RTBUS. */
280
281 chipcHw_setClockFrequency(chipcHw_CLOCK_ARM,
282 initParam->busClockFreqHz *
283 initParam->armBusRatio);
284 chipcHw_setClockFrequency(chipcHw_CLOCK_BUS, initParam->busClockFreqHz);
285 chipcHw_setClockFrequency(chipcHw_CLOCK_VPM,
286 initParam->busClockFreqHz *
287 initParam->vpmBusRatio);
288 chipcHw_setClockFrequency(chipcHw_CLOCK_DDR,
289 initParam->busClockFreqHz *
290 initParam->ddrBusRatio);
291 chipcHw_setClockFrequency(chipcHw_CLOCK_RTBUS,
292 initParam->busClockFreqHz / 2);
293}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
new file mode 100644
index 000000000000..2671d8896bbb
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
@@ -0,0 +1,124 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/* ---- Include Files ---------------------------------------------------- */
16#include <csp/stdint.h>
17#include <mach/csp/chipcHw_def.h>
18#include <mach/csp/chipcHw_inline.h>
19#include <csp/intcHw.h>
20#include <csp/cache.h>
21
22/* ---- Private Constants and Types --------------------------------------- */
23/* ---- Private Variables ------------------------------------------------- */
24void chipcHw_reset_run_from_aram(void);
25
26typedef void (*RUNFUNC) (void);
27
28/****************************************************************************/
29/**
30* @brief warmReset
31*
32* @note warmReset configures the clocks which are not reset back to the state
33* required to execute on reset. To do so we need to copy the code into internal
34* memory to change the ARM clock while we are not executing from DDR.
35*/
36/****************************************************************************/
37void chipcHw_reset(uint32_t mask)
38{
39 int i = 0;
40 RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;
41
42 /* Disable all interrupts */
43 intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);
44 intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);
45 intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);
46
47 {
48 REG_LOCAL_IRQ_SAVE;
49 if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {
50 chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
51 }
52 /* Bypass the PLL clocks before reboot */
53 pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
54 pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
55
56 /* Copy the chipcHw_warmReset_run_from_aram function into ARAM */
57 do {
58 ((uint32_t *) MM_IO_BASE_ARAM)[i] =
59 ((uint32_t *) &chipcHw_reset_run_from_aram)[i];
60 i++;
61 } while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f); /* 0xe1a0f00f == asm ("mov r15, r15"); */
62
63 CSP_CACHE_FLUSH_ALL;
64
65 /* run the function from ARAM */
66 runFunc();
67
68 /* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */
69 REG_LOCAL_IRQ_RESTORE;
70 }
71}
72
73/* This function must run from internal memory */
74void chipcHw_reset_run_from_aram(void)
75{
76/* Make sure, pipeline is filled with instructions coming from ARAM */
77__asm (" nop \n\t"
78 " nop \n\t"
79#if defined(__KERNEL__) && !defined(STANDALONE)
80 " MRC p15,#0x0,r0,c1,c0,#0 \n\t"
81 " BIC r0,r0,#0xd \n\t"
82 " MCR p15,#0x0,r0,c1,c0,#0 \n\t"
83 " nop \n\t"
84 " nop \n\t"
85 " nop \n\t"
86 " nop \n\t"
87 " nop \n\t"
88 " nop \n\t"
89#endif
90 " nop \n\t"
91 " nop \n\t"
92/* Bypass the ARM clock and switch to XTAL clock */
93 " MOV r2,#0x80000000 \n\t"
94 " LDR r3,[r2,#8] \n\t"
95 " ORR r3,r3,#0x20000 \n\t"
96 " STR r3,[r2,#8] \n\t"
97
98 " nop \n\t"
99 " nop \n\t"
100 " nop \n\t"
101 " nop \n\t"
102 " nop \n\t"
103 " nop \n\t"
104 " nop \n\t"
105 " nop \n\t"
106 " nop \n\t"
107 " nop \n\t"
108 " nop \n\t"
109 " nop \n\t"
110 " nop \n\t"
111 " nop \n\t"
112 " nop \n\t"
113 " nop \n\t"
114 " nop \n\t"
115 " nop \n\t"
116 " nop \n\t"
117 " nop \n\t"
118/* Issue reset */
119 " MOV r3,#0x2 \n\t"
120 " STR r3,[r2,#0x80] \n\t"
121/* End here */
122 " MOV pc,pc \n\t");
123/* 0xe1a0f00f == asm ("mov r15, r15"); */
124}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
new file mode 100644
index 000000000000..54ad964fe94c
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
@@ -0,0 +1,64 @@
1/*****************************************************************************
2* Copyright 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14/****************************************************************************/
15/**
16* @file chipcHw_str.c
17*
18* @brief Contains strings which are useful to linux and csp
19*
20* @note
21*/
22/****************************************************************************/
23
24/* ---- Include Files ---------------------------------------------------- */
25
26#include <mach/csp/chipcHw_inline.h>
27
28/* ---- Private Constants and Types --------------------------------------- */
29
30static const char *gMuxStr[] = {
31 "GPIO", /* 0 */
32 "KeyPad", /* 1 */
33 "I2C-Host", /* 2 */
34 "SPI", /* 3 */
35 "Uart", /* 4 */
36 "LED-Mtx-P", /* 5 */
37 "LED-Mtx-S", /* 6 */
38 "SDIO-0", /* 7 */
39 "SDIO-1", /* 8 */
40 "PCM", /* 9 */
41 "I2S", /* 10 */
42 "ETM", /* 11 */
43 "Debug", /* 12 */
44 "Misc", /* 13 */
45 "0xE", /* 14 */
46 "0xF", /* 15 */
47};
48
49/****************************************************************************/
50/**
51* @brief Retrieves a string representation of the mux setting for a pin.
52*
53* @return Pointer to a character string.
54*/
55/****************************************************************************/
56
57const char *chipcHw_getGpioPinFunctionStr(int pin)
58{
59 if ((pin < 0) || (pin >= chipcHw_GPIO_COUNT)) {
60 return "";
61 }
62
63 return gMuxStr[chipcHw_getGpioPinFunction(pin)];
64}
diff --git a/arch/arm/mach-bcmring/csp/dmac/Makefile b/arch/arm/mach-bcmring/csp/dmac/Makefile
new file mode 100644
index 000000000000..fb1104fe56b2
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/Makefile
@@ -0,0 +1 @@
obj-y += dmacHw.o dmacHw_extra.o \ No newline at end of file
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c
new file mode 100644
index 000000000000..7b9bac2d79a5
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c
@@ -0,0 +1,917 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dmacHw.c
18*
19* @brief Low level DMA controller driver routines
20*
21* @note
22*
23* These routines provide basic DMA functionality only.
24*/
25/****************************************************************************/
26
27/* ---- Include Files ---------------------------------------------------- */
28#include <csp/stdint.h>
29#include <csp/string.h>
30#include <stddef.h>
31
32#include <csp/dmacHw.h>
33#include <mach/csp/dmacHw_reg.h>
34#include <mach/csp/dmacHw_priv.h>
35#include <mach/csp/chipcHw_inline.h>
36
37/* ---- External Function Prototypes ------------------------------------- */
38
39/* Allocate DMA control blocks */
40dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT];
41
42uint32_t dmaChannelCount_0 = dmacHw_MAX_CHANNEL_COUNT / 2;
43uint32_t dmaChannelCount_1 = dmacHw_MAX_CHANNEL_COUNT / 2;
44
45/****************************************************************************/
46/**
47* @brief Get maximum FIFO for a DMA channel
48*
49* @return Maximum allowable FIFO size
50*
51*
52*/
53/****************************************************************************/
54static uint32_t GetFifoSize(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
55 ) {
56 uint32_t val = 0;
57 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
58 dmacHw_MISC_t *pMiscReg =
59 (dmacHw_MISC_t *) dmacHw_REG_MISC_BASE(pCblk->module);
60
61 switch (pCblk->channel) {
62 case 0:
63 val = (pMiscReg->CompParm2.lo & 0x70000000) >> 28;
64 break;
65 case 1:
66 val = (pMiscReg->CompParm3.hi & 0x70000000) >> 28;
67 break;
68 case 2:
69 val = (pMiscReg->CompParm3.lo & 0x70000000) >> 28;
70 break;
71 case 3:
72 val = (pMiscReg->CompParm4.hi & 0x70000000) >> 28;
73 break;
74 case 4:
75 val = (pMiscReg->CompParm4.lo & 0x70000000) >> 28;
76 break;
77 case 5:
78 val = (pMiscReg->CompParm5.hi & 0x70000000) >> 28;
79 break;
80 case 6:
81 val = (pMiscReg->CompParm5.lo & 0x70000000) >> 28;
82 break;
83 case 7:
84 val = (pMiscReg->CompParm6.hi & 0x70000000) >> 28;
85 break;
86 }
87
88 if (val <= 0x4) {
89 return 8 << val;
90 } else {
91 dmacHw_ASSERT(0);
92 }
93 return 0;
94}
95
96/****************************************************************************/
97/**
98* @brief Program channel register to initiate transfer
99*
100* @return void
101*
102*
103* @note
104* - Descriptor buffer MUST ALWAYS be flushed before calling this function
105* - This function should also be called from ISR to program the channel with
106* pending descriptors
107*/
108/****************************************************************************/
109void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
110 dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
111 void *pDescriptor /* [ IN ] Descriptor buffer */
112 ) {
113 dmacHw_DESC_RING_t *pRing;
114 dmacHw_DESC_t *pProg;
115 dmacHw_CBLK_t *pCblk;
116
117 pCblk = dmacHw_HANDLE_TO_CBLK(handle);
118 pRing = dmacHw_GET_DESC_RING(pDescriptor);
119
120 if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
121 /* Not safe yet to program the channel */
122 return;
123 }
124
125 if (pCblk->varDataStarted) {
126 if (pCblk->descUpdated) {
127 pCblk->descUpdated = 0;
128 pProg =
129 (dmacHw_DESC_t *) ((uint32_t)
130 dmacHw_REG_LLP(pCblk->module,
131 pCblk->channel) +
132 pRing->virt2PhyOffset);
133
134 /* Load descriptor if not loaded */
135 if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
136 dmacHw_SET_SAR(pCblk->module, pCblk->channel,
137 pProg->sar);
138 dmacHw_SET_DAR(pCblk->module, pCblk->channel,
139 pProg->dar);
140 dmacHw_REG_CTL_LO(pCblk->module,
141 pCblk->channel) =
142 pProg->ctl.lo;
143 dmacHw_REG_CTL_HI(pCblk->module,
144 pCblk->channel) =
145 pProg->ctl.hi;
146 } else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
147 /* Return as end descriptor is processed */
148 return;
149 } else {
150 dmacHw_ASSERT(0);
151 }
152 } else {
153 return;
154 }
155 } else {
156 if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
157 /* Do not make a single chain, rather process one descriptor at a time */
158 pProg = pRing->pHead;
159 /* Point to the next descriptor for next iteration */
160 dmacHw_NEXT_DESC(pRing, pHead);
161 } else {
162 /* Return if no more pending descriptor */
163 if (pRing->pEnd == NULL) {
164 return;
165 }
166
167 pProg = pRing->pProg;
168 if (pConfig->transferMode ==
169 dmacHw_TRANSFER_MODE_CONTINUOUS) {
170 /* Make sure a complete ring can be formed */
171 dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
172 llp == pRing->pProg);
173 /* Make sure pProg pointing to the pHead */
174 dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
175 pRing->pHead);
176 /* Make a complete ring */
177 do {
178 pRing->pProg->ctl.lo |=
179 (dmacHw_REG_CTL_LLP_DST_EN |
180 dmacHw_REG_CTL_LLP_SRC_EN);
181 pRing->pProg =
182 (dmacHw_DESC_t *) pRing->pProg->llp;
183 } while (pRing->pProg != pRing->pHead);
184 } else {
185 /* Make a single long chain */
186 while (pRing->pProg != pRing->pEnd) {
187 pRing->pProg->ctl.lo |=
188 (dmacHw_REG_CTL_LLP_DST_EN |
189 dmacHw_REG_CTL_LLP_SRC_EN);
190 pRing->pProg =
191 (dmacHw_DESC_t *) pRing->pProg->llp;
192 }
193 }
194 }
195
196 /* Program the channel registers */
197 dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
198 dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
199 dmacHw_SET_LLP(pCblk->module, pCblk->channel,
200 (uint32_t) pProg - pRing->virt2PhyOffset);
201 dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
202 pProg->ctl.lo;
203 dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
204 pProg->ctl.hi;
205 if (pRing->pEnd) {
206 /* Remember the descriptor to use next */
207 pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
208 }
209 /* Indicate no more pending descriptor */
210 pRing->pEnd = (dmacHw_DESC_t *) NULL;
211 }
212 /* Start DMA operation */
213 dmacHw_DMA_START(pCblk->module, pCblk->channel);
214}
215
216/****************************************************************************/
217/**
218* @brief Initializes DMA
219*
220* This function initializes DMA CSP driver
221*
222* @note
223* Must be called before using any DMA channel
224*/
225/****************************************************************************/
226void dmacHw_initDma(void)
227{
228
229 uint32_t i = 0;
230
231 dmaChannelCount_0 = dmacHw_GET_NUM_CHANNEL(0);
232 dmaChannelCount_1 = dmacHw_GET_NUM_CHANNEL(1);
233
234 /* Enable access to the DMA block */
235 chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC0);
236 chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC1);
237
238 if ((dmaChannelCount_0 + dmaChannelCount_1) > dmacHw_MAX_CHANNEL_COUNT) {
239 dmacHw_ASSERT(0);
240 }
241
242 memset((void *)dmacHw_gCblk, 0,
243 sizeof(dmacHw_CBLK_t) * (dmaChannelCount_0 + dmaChannelCount_1));
244 for (i = 0; i < dmaChannelCount_0; i++) {
245 dmacHw_gCblk[i].module = 0;
246 dmacHw_gCblk[i].channel = i;
247 }
248 for (i = 0; i < dmaChannelCount_1; i++) {
249 dmacHw_gCblk[i + dmaChannelCount_0].module = 1;
250 dmacHw_gCblk[i + dmaChannelCount_0].channel = i;
251 }
252}
253
254/****************************************************************************/
255/**
256* @brief Exit function for DMA
257*
258* This function isolates DMA from the system
259*
260*/
261/****************************************************************************/
262void dmacHw_exitDma(void)
263{
264 /* Disable access to the DMA block */
265 chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC0);
266 chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC1);
267}
268
269/****************************************************************************/
270/**
271* @brief Gets a handle to a DMA channel
272*
273* This function returns a handle, representing a control block of a particular DMA channel
274*
275* @return -1 - On Failure
276* handle - On Success, representing a channel control block
277*
278* @note
279* None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
280*/
281/****************************************************************************/
282dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */
283 ) {
284 int idx;
285
286 switch ((channelId >> 8)) {
287 case 0:
288 dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_0);
289 idx = (channelId & 0xff);
290 break;
291 case 1:
292 dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_1);
293 idx = dmaChannelCount_0 + (channelId & 0xff);
294 break;
295 default:
296 dmacHw_ASSERT(0);
297 return (dmacHw_HANDLE_t) -1;
298 }
299
300 return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[idx]);
301}
302
303/****************************************************************************/
304/**
305* @brief Initializes a DMA channel for use
306*
307* This function initializes and resets a DMA channel for use
308*
309* @return -1 - On Failure
310* 0 - On Success
311*
312* @note
313* None
314*/
315/****************************************************************************/
316int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
317 ) {
318 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
319 int module = pCblk->module;
320 int channel = pCblk->channel;
321
322 /* Reinitialize the control block */
323 memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t));
324 pCblk->module = module;
325 pCblk->channel = channel;
326
327 /* Enable DMA controller */
328 dmacHw_DMA_ENABLE(pCblk->module);
329 /* Reset DMA channel */
330 dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel);
331 dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel);
332 dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel);
333 dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel);
334
335 /* Clear all raw interrupt status */
336 dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
337 dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
338 dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
339
340 /* Mask event specific interrupts */
341 dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
342 dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
343 dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel);
344 dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel);
345 dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
346
347 return 0;
348}
349
350/****************************************************************************/
351/**
352* @brief Finds amount of memory required to form a descriptor ring
353*
354*
355* @return Number of bytes required to form a descriptor ring
356*
357*
358*/
359/****************************************************************************/
360uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */
361 ) {
362 /* Need extra 4 byte to ensure 32 bit alignment */
363 return (descCnt * sizeof(dmacHw_DESC_t)) + sizeof(dmacHw_DESC_RING_t) +
364 sizeof(uint32_t);
365}
366
367/****************************************************************************/
368/**
369* @brief Initializes descriptor ring
370*
371* This function will initializes the descriptor ring of a DMA channel
372*
373*
374* @return -1 - On failure
375* 0 - On success
376* @note
377* - "len" parameter should be obtained from "dmacHw_descriptorLen"
378* - Descriptor buffer MUST be 32 bit aligned and uncached as it is
379* accessed by ARM and DMA
380*/
381/****************************************************************************/
382int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
383 uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
384 uint32_t len, /* [ IN ] Size of the pBuf */
385 uint32_t num /* [ IN ] Number of descriptor in the ring */
386 ) {
387 uint32_t i;
388 dmacHw_DESC_RING_t *pRing;
389 dmacHw_DESC_t *pDesc;
390
391 /* Check the alignment of the descriptor */
392 if ((uint32_t) pDescriptorVirt & 0x00000003) {
393 dmacHw_ASSERT(0);
394 return -1;
395 }
396
397 /* Check if enough space has been allocated for descriptor ring */
398 if (len < dmacHw_descriptorLen(num)) {
399 return -1;
400 }
401
402 pRing = dmacHw_GET_DESC_RING(pDescriptorVirt);
403 pRing->pHead =
404 (dmacHw_DESC_t *) ((uint32_t) pRing + sizeof(dmacHw_DESC_RING_t));
405 pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
406 pRing->pProg = dmacHw_DESC_INIT;
407 /* Initialize link item chain, starting from the head */
408 pDesc = pRing->pHead;
409 /* Find the offset between virtual to physical address */
410 pRing->virt2PhyOffset = (uint32_t) pDescriptorVirt - descriptorPhyAddr;
411
412 /* Form the descriptor ring */
413 for (i = 0; i < num - 1; i++) {
414 /* Clear link list item */
415 memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
416 /* Point to the next item in the physical address */
417 pDesc->llpPhy = (uint32_t) (pDesc + 1) - pRing->virt2PhyOffset;
418 /* Point to the next item in the virtual address */
419 pDesc->llp = (uint32_t) (pDesc + 1);
420 /* Mark descriptor is ready to use */
421 pDesc->ctl.hi = dmacHw_DESC_FREE;
422 /* Look into next link list item */
423 pDesc++;
424 }
425
426 /* Clear last link list item */
427 memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
428 /* Last item pointing to the first item in the
429 physical address to complete the ring */
430 pDesc->llpPhy = (uint32_t) pRing->pHead - pRing->virt2PhyOffset;
431 /* Last item pointing to the first item in the
432 virtual address to complete the ring
433 */
434 pDesc->llp = (uint32_t) pRing->pHead;
435 /* Mark descriptor is ready to use */
436 pDesc->ctl.hi = dmacHw_DESC_FREE;
437 /* Set the number of descriptors in the ring */
438 pRing->num = num;
439 return 0;
440}
441
442/****************************************************************************/
443/**
444* @brief Configure DMA channel
445*
446* @return 0 : On success
447* -1 : On failure
448*/
449/****************************************************************************/
450int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
451 dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */
452 ) {
453 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
454 uint32_t cfgHigh = 0;
455 int srcTrSize;
456 int dstTrSize;
457
458 pCblk->varDataStarted = 0;
459 pCblk->userData = NULL;
460
461 /* Configure
462 - Burst transaction when enough data in available in FIFO
463 - AHB Access protection 1
464 - Source and destination peripheral ports
465 */
466 cfgHigh =
467 dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 |
468 dmacHw_SRC_PERI_INTF(pConfig->
469 srcPeripheralPort) |
470 dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort);
471 /* Set priority */
472 dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel,
473 pConfig->channelPriority);
474
475 if (pConfig->dstStatusRegisterAddress != 0) {
476 /* Destination status update enable */
477 cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT;
478 /* Configure status registers */
479 dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel,
480 pConfig->dstStatusRegisterAddress);
481 }
482
483 if (pConfig->srcStatusRegisterAddress != 0) {
484 /* Source status update enable */
485 cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT;
486 /* Source status update enable */
487 dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel,
488 pConfig->srcStatusRegisterAddress);
489 }
490 /* Configure the config high register */
491 dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh;
492
493 /* Clear all raw interrupt status */
494 dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
495 dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
496 dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
497
498 /* Configure block interrupt */
499 if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
500 dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel);
501 } else {
502 dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
503 }
504 /* Configure complete transfer interrupt */
505 if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
506 dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel);
507 } else {
508 dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
509 }
510 /* Configure error interrupt */
511 if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) {
512 dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel);
513 } else {
514 dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
515 }
516 /* Configure gather register */
517 if (pConfig->srcGatherWidth) {
518 srcTrSize =
519 dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
520 if (!
521 ((pConfig->srcGatherWidth % srcTrSize)
522 && (pConfig->srcGatherJump % srcTrSize))) {
523 dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) =
524 ((pConfig->srcGatherWidth /
525 srcTrSize) << 20) | (pConfig->srcGatherJump /
526 srcTrSize);
527 } else {
528 return -1;
529 }
530 }
531 /* Configure scatter register */
532 if (pConfig->dstScatterWidth) {
533 dstTrSize =
534 dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
535 if (!
536 ((pConfig->dstScatterWidth % dstTrSize)
537 && (pConfig->dstScatterJump % dstTrSize))) {
538 dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) =
539 ((pConfig->dstScatterWidth /
540 dstTrSize) << 20) | (pConfig->dstScatterJump /
541 dstTrSize);
542 } else {
543 return -1;
544 }
545 }
546 return 0;
547}
548
549/****************************************************************************/
550/**
551* @brief Indicates whether DMA transfer is in progress or completed
552*
553* @return DMA transfer status
554* dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing
555* dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed
556* dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error
557*
558*/
559/****************************************************************************/
560dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
561 ) {
562 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
563
564 if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
565 return dmacHw_TRANSFER_STATUS_BUSY;
566 } else if (dmacHw_REG_INT_RAW_ERROR(pCblk->module) &
567 (0x00000001 << pCblk->channel)) {
568 return dmacHw_TRANSFER_STATUS_ERROR;
569 }
570
571 return dmacHw_TRANSFER_STATUS_DONE;
572}
573
574/****************************************************************************/
575/**
576* @brief Set descriptors for known data length
577*
578* When DMA has to work as a flow controller, this function prepares the
579* descriptor chain to transfer data
580*
581* from:
582* - Memory to memory
583* - Peripheral to memory
584* - Memory to Peripheral
585* - Peripheral to Peripheral
586*
587* @return -1 - On failure
588* 0 - On success
589*
590*/
591/****************************************************************************/
592int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
593 void *pDescriptor, /* [ IN ] Descriptor buffer */
594 void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
595 void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
596 size_t dataLen /* [ IN ] Data length in bytes */
597 ) {
598 dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
599 dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
600 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
601 dmacHw_DESC_t *pStart;
602 dmacHw_DESC_t *pProg;
603 int srcTs = 0;
604 int blkTs = 0;
605 int oddSize = 0;
606 int descCount = 0;
607 int count = 0;
608 int dstTrSize = 0;
609 int srcTrSize = 0;
610 uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
611
612 dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
613 srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
614
615 /* Skip Tx if buffer is NULL or length is unknown */
616 if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
617 /* Do not initiate transfer */
618 return -1;
619 }
620
621 /* Ensure scatter and gather are transaction aligned */
622 if ((pConfig->srcGatherWidth % srcTrSize)
623 || (pConfig->dstScatterWidth % dstTrSize)) {
624 return -2;
625 }
626
627 /*
628 Background 1: DMAC can not perform DMA if source and destination addresses are
629 not properly aligned with the channel's transaction width. So, for successful
630 DMA transfer, transaction width must be set according to the alignment of the
631 source and destination address.
632 */
633
634 /* Adjust destination transaction width if destination address is not aligned properly */
635 dstTrWidth = pConfig->dstMaxTransactionWidth;
636 while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
637 dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
638 dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
639 }
640
641 /* Adjust source transaction width if source address is not aligned properly */
642 srcTrWidth = pConfig->srcMaxTransactionWidth;
643 while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
644 srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
645 srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
646 }
647
648 /* Find the maximum transaction per descriptor */
649 if (pConfig->maxDataPerBlock
650 && ((pConfig->maxDataPerBlock / srcTrSize) <
651 dmacHw_MAX_BLOCKSIZE)) {
652 maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
653 }
654
655 /* Find number of source transactions needed to complete the DMA transfer */
656 srcTs = dataLen / srcTrSize;
657 /* Find the odd number of bytes that need to be transferred as single byte transaction width */
658 if (srcTs && (dstTrSize > srcTrSize)) {
659 oddSize = dataLen % dstTrSize;
660 /* Adjust source transaction count due to "oddSize" */
661 srcTs = srcTs - (oddSize / srcTrSize);
662 } else {
663 oddSize = dataLen % srcTrSize;
664 }
665 /* Adjust "descCount" due to "oddSize" */
666 if (oddSize) {
667 descCount++;
668 }
669 /* Find the number of descriptor needed for total "srcTs" */
670 if (srcTs) {
671 descCount += ((srcTs - 1) / maxBlockSize) + 1;
672 }
673
674 /* Check the availability of "descCount" discriptors in the ring */
675 pProg = pRing->pHead;
676 for (count = 0; (descCount <= pRing->num) && (count < descCount);
677 count++) {
678 if ((pProg->ctl.hi & dmacHw_DESC_FREE) == 0) {
679 /* Sufficient descriptors are not available */
680 return -3;
681 }
682 pProg = (dmacHw_DESC_t *) pProg->llp;
683 }
684
685 /* Remember the link list item to program the channel registers */
686 pStart = pProg = pRing->pHead;
687 /* Make a link list with "descCount(=count)" number of descriptors */
688 while (count) {
689 /* Reset channel control information */
690 pProg->ctl.lo = 0;
691 /* Enable source gather if configured */
692 if (pConfig->srcGatherWidth) {
693 pProg->ctl.lo |= dmacHw_REG_CTL_SG_ENABLE;
694 }
695 /* Enable destination scatter if configured */
696 if (pConfig->dstScatterWidth) {
697 pProg->ctl.lo |= dmacHw_REG_CTL_DS_ENABLE;
698 }
699 /* Set source and destination address */
700 pProg->sar = (uint32_t) pSrcAddr;
701 pProg->dar = (uint32_t) pDstAddr;
702 /* Use "devCtl" to mark that user memory need to be freed later if needed */
703 if (pProg == pRing->pHead) {
704 pProg->devCtl = dmacHw_FREE_USER_MEMORY;
705 } else {
706 pProg->devCtl = 0;
707 }
708
709 blkTs = srcTs;
710
711 /* Special treatmeant for last descriptor */
712 if (count == 1) {
713 /* Mark the last descriptor */
714 pProg->ctl.lo &=
715 ~(dmacHw_REG_CTL_LLP_DST_EN |
716 dmacHw_REG_CTL_LLP_SRC_EN);
717 /* Treatment for odd data bytes */
718 if (oddSize) {
719 /* Adjust for single byte transaction width */
720 switch (pConfig->transferType) {
721 case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
722 dstTrWidth =
723 dmacHw_DST_TRANSACTION_WIDTH_8;
724 blkTs =
725 (oddSize / srcTrSize) +
726 ((oddSize % srcTrSize) ? 1 : 0);
727 break;
728 case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
729 srcTrWidth =
730 dmacHw_SRC_TRANSACTION_WIDTH_8;
731 blkTs = oddSize;
732 break;
733 case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
734 srcTrWidth =
735 dmacHw_SRC_TRANSACTION_WIDTH_8;
736 dstTrWidth =
737 dmacHw_DST_TRANSACTION_WIDTH_8;
738 blkTs = oddSize;
739 break;
740 case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
741 /* Do not adjust the transaction width */
742 break;
743 }
744 } else {
745 srcTs -= blkTs;
746 }
747 } else {
748 if (srcTs / maxBlockSize) {
749 blkTs = maxBlockSize;
750 }
751 /* Remaining source transactions for next iteration */
752 srcTs -= blkTs;
753 }
754 /* Must have a valid source transactions */
755 dmacHw_ASSERT(blkTs > 0);
756 /* Set control information */
757 if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
758 pProg->ctl.lo |= pConfig->transferType |
759 pConfig->srcUpdate |
760 pConfig->dstUpdate |
761 srcTrWidth |
762 dstTrWidth |
763 pConfig->srcMaxBurstWidth |
764 pConfig->dstMaxBurstWidth |
765 pConfig->srcMasterInterface |
766 pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
767 } else {
768 uint32_t transferType = 0;
769 switch (pConfig->transferType) {
770 case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
771 transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
772 break;
773 case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
774 transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
775 break;
776 default:
777 dmacHw_ASSERT(0);
778 }
779 pProg->ctl.lo |= transferType |
780 pConfig->srcUpdate |
781 pConfig->dstUpdate |
782 srcTrWidth |
783 dstTrWidth |
784 pConfig->srcMaxBurstWidth |
785 pConfig->dstMaxBurstWidth |
786 pConfig->srcMasterInterface |
787 pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
788 }
789
790 /* Set block transaction size */
791 pProg->ctl.hi = blkTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
792 /* Look for next descriptor */
793 if (count > 1) {
794 /* Point to the next descriptor */
795 pProg = (dmacHw_DESC_t *) pProg->llp;
796
797 /* Update source and destination address for next iteration */
798 switch (pConfig->transferType) {
799 case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
800 if (pConfig->dstScatterWidth) {
801 pDstAddr =
802 (char *)pDstAddr +
803 blkTs * srcTrSize +
804 (((blkTs * srcTrSize) /
805 pConfig->dstScatterWidth) *
806 pConfig->dstScatterJump);
807 } else {
808 pDstAddr =
809 (char *)pDstAddr +
810 blkTs * srcTrSize;
811 }
812 break;
813 case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
814 if (pConfig->srcGatherWidth) {
815 pSrcAddr =
816 (char *)pDstAddr +
817 blkTs * srcTrSize +
818 (((blkTs * srcTrSize) /
819 pConfig->srcGatherWidth) *
820 pConfig->srcGatherJump);
821 } else {
822 pSrcAddr =
823 (char *)pSrcAddr +
824 blkTs * srcTrSize;
825 }
826 break;
827 case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
828 if (pConfig->dstScatterWidth) {
829 pDstAddr =
830 (char *)pDstAddr +
831 blkTs * srcTrSize +
832 (((blkTs * srcTrSize) /
833 pConfig->dstScatterWidth) *
834 pConfig->dstScatterJump);
835 } else {
836 pDstAddr =
837 (char *)pDstAddr +
838 blkTs * srcTrSize;
839 }
840
841 if (pConfig->srcGatherWidth) {
842 pSrcAddr =
843 (char *)pDstAddr +
844 blkTs * srcTrSize +
845 (((blkTs * srcTrSize) /
846 pConfig->srcGatherWidth) *
847 pConfig->srcGatherJump);
848 } else {
849 pSrcAddr =
850 (char *)pSrcAddr +
851 blkTs * srcTrSize;
852 }
853 break;
854 case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
855 /* Do not adjust the address */
856 break;
857 default:
858 dmacHw_ASSERT(0);
859 }
860 } else {
861 /* At the end of transfer "srcTs" must be zero */
862 dmacHw_ASSERT(srcTs == 0);
863 }
864 count--;
865 }
866
867 /* Remember the descriptor to initialize the registers */
868 if (pRing->pProg == dmacHw_DESC_INIT) {
869 pRing->pProg = pStart;
870 }
871 /* Indicate that the descriptor is updated */
872 pRing->pEnd = pProg;
873 /* Head pointing to the next descriptor */
874 pRing->pHead = (dmacHw_DESC_t *) pProg->llp;
875 /* Update Tail pointer if destination is a peripheral,
876 because no one is going to read from the pTail
877 */
878 if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
879 pRing->pTail = pRing->pHead;
880 }
881 return 0;
882}
883
884/****************************************************************************/
885/**
886* @brief Provides DMA controller attributes
887*
888*
889* @return DMA controller attributes
890*
891* @note
892* None
893*/
894/****************************************************************************/
895uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
896 dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */
897 ) {
898 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
899
900 switch (attr) {
901 case dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM:
902 return dmacHw_GET_NUM_CHANNEL(pCblk->module);
903 case dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE:
904 return (1 <<
905 (dmacHw_GET_MAX_BLOCK_SIZE
906 (pCblk->module, pCblk->module) + 2)) - 8;
907 case dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM:
908 return dmacHw_GET_NUM_INTERFACE(pCblk->module);
909 case dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH:
910 return 32 << dmacHw_GET_CHANNEL_DATA_WIDTH(pCblk->module,
911 pCblk->channel);
912 case dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE:
913 return GetFifoSize(handle);
914 }
915 dmacHw_ASSERT(0);
916 return 0;
917}
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c
new file mode 100644
index 000000000000..ff7b436d0935
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c
@@ -0,0 +1,1017 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dmacHw_extra.c
18*
19* @brief Extra Low level DMA controller driver routines
20*
21* @note
22*
23* These routines provide basic DMA functionality only.
24*/
25/****************************************************************************/
26
27/* ---- Include Files ---------------------------------------------------- */
28
29#include <csp/stdint.h>
30#include <stddef.h>
31
32#include <csp/dmacHw.h>
33#include <mach/csp/dmacHw_reg.h>
34#include <mach/csp/dmacHw_priv.h>
35
36extern dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT]; /* Declared in dmacHw.c */
37
38/* ---- External Function Prototypes ------------------------------------- */
39
40/* ---- Internal Use Function Prototypes --------------------------------- */
41/****************************************************************************/
42/**
43* @brief Overwrites data length in the descriptor
44*
45* This function overwrites data length in the descriptor
46*
47*
48* @return void
49*
50* @note
51* This is only used for PCM channel
52*/
53/****************************************************************************/
54void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
55 void *pDescriptor, /* [ IN ] Descriptor buffer */
56 size_t dataLen /* [ IN ] Data length in bytes */
57 );
58
59/****************************************************************************/
60/**
61* @brief Helper function to display DMA registers
62*
63* @return void
64*
65*
66* @note
67* None
68*/
69/****************************************************************************/
70static void DisplayRegisterContents(int module, /* [ IN ] DMA Controller unit (0-1) */
71 int channel, /* [ IN ] DMA Channel (0-7) / -1(all) */
72 int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */
73 ) {
74 int chan;
75
76 (*fpPrint) ("Displaying register content \n\n");
77 (*fpPrint) ("Module %d: Interrupt raw transfer 0x%X\n",
78 module, (uint32_t) (dmacHw_REG_INT_RAW_TRAN(module)));
79 (*fpPrint) ("Module %d: Interrupt raw block 0x%X\n",
80 module, (uint32_t) (dmacHw_REG_INT_RAW_BLOCK(module)));
81 (*fpPrint) ("Module %d: Interrupt raw src transfer 0x%X\n",
82 module, (uint32_t) (dmacHw_REG_INT_RAW_STRAN(module)));
83 (*fpPrint) ("Module %d: Interrupt raw dst transfer 0x%X\n",
84 module, (uint32_t) (dmacHw_REG_INT_RAW_DTRAN(module)));
85 (*fpPrint) ("Module %d: Interrupt raw error 0x%X\n",
86 module, (uint32_t) (dmacHw_REG_INT_RAW_ERROR(module)));
87 (*fpPrint) ("--------------------------------------------------\n");
88 (*fpPrint) ("Module %d: Interrupt stat transfer 0x%X\n",
89 module, (uint32_t) (dmacHw_REG_INT_STAT_TRAN(module)));
90 (*fpPrint) ("Module %d: Interrupt stat block 0x%X\n",
91 module, (uint32_t) (dmacHw_REG_INT_STAT_BLOCK(module)));
92 (*fpPrint) ("Module %d: Interrupt stat src transfer 0x%X\n",
93 module, (uint32_t) (dmacHw_REG_INT_STAT_STRAN(module)));
94 (*fpPrint) ("Module %d: Interrupt stat dst transfer 0x%X\n",
95 module, (uint32_t) (dmacHw_REG_INT_STAT_DTRAN(module)));
96 (*fpPrint) ("Module %d: Interrupt stat error 0x%X\n",
97 module, (uint32_t) (dmacHw_REG_INT_STAT_ERROR(module)));
98 (*fpPrint) ("--------------------------------------------------\n");
99 (*fpPrint) ("Module %d: Interrupt mask transfer 0x%X\n",
100 module, (uint32_t) (dmacHw_REG_INT_MASK_TRAN(module)));
101 (*fpPrint) ("Module %d: Interrupt mask block 0x%X\n",
102 module, (uint32_t) (dmacHw_REG_INT_MASK_BLOCK(module)));
103 (*fpPrint) ("Module %d: Interrupt mask src transfer 0x%X\n",
104 module, (uint32_t) (dmacHw_REG_INT_MASK_STRAN(module)));
105 (*fpPrint) ("Module %d: Interrupt mask dst transfer 0x%X\n",
106 module, (uint32_t) (dmacHw_REG_INT_MASK_DTRAN(module)));
107 (*fpPrint) ("Module %d: Interrupt mask error 0x%X\n",
108 module, (uint32_t) (dmacHw_REG_INT_MASK_ERROR(module)));
109 (*fpPrint) ("--------------------------------------------------\n");
110 (*fpPrint) ("Module %d: Interrupt clear transfer 0x%X\n",
111 module, (uint32_t) (dmacHw_REG_INT_CLEAR_TRAN(module)));
112 (*fpPrint) ("Module %d: Interrupt clear block 0x%X\n",
113 module, (uint32_t) (dmacHw_REG_INT_CLEAR_BLOCK(module)));
114 (*fpPrint) ("Module %d: Interrupt clear src transfer 0x%X\n",
115 module, (uint32_t) (dmacHw_REG_INT_CLEAR_STRAN(module)));
116 (*fpPrint) ("Module %d: Interrupt clear dst transfer 0x%X\n",
117 module, (uint32_t) (dmacHw_REG_INT_CLEAR_DTRAN(module)));
118 (*fpPrint) ("Module %d: Interrupt clear error 0x%X\n",
119 module, (uint32_t) (dmacHw_REG_INT_CLEAR_ERROR(module)));
120 (*fpPrint) ("--------------------------------------------------\n");
121 (*fpPrint) ("Module %d: SW source req 0x%X\n",
122 module, (uint32_t) (dmacHw_REG_SW_HS_SRC_REQ(module)));
123 (*fpPrint) ("Module %d: SW dest req 0x%X\n",
124 module, (uint32_t) (dmacHw_REG_SW_HS_DST_REQ(module)));
125 (*fpPrint) ("Module %d: SW source signal 0x%X\n",
126 module, (uint32_t) (dmacHw_REG_SW_HS_SRC_SGL_REQ(module)));
127 (*fpPrint) ("Module %d: SW dest signal 0x%X\n",
128 module, (uint32_t) (dmacHw_REG_SW_HS_DST_SGL_REQ(module)));
129 (*fpPrint) ("Module %d: SW source last 0x%X\n",
130 module, (uint32_t) (dmacHw_REG_SW_HS_SRC_LST_REQ(module)));
131 (*fpPrint) ("Module %d: SW dest last 0x%X\n",
132 module, (uint32_t) (dmacHw_REG_SW_HS_DST_LST_REQ(module)));
133 (*fpPrint) ("--------------------------------------------------\n");
134 (*fpPrint) ("Module %d: misc config 0x%X\n",
135 module, (uint32_t) (dmacHw_REG_MISC_CFG(module)));
136 (*fpPrint) ("Module %d: misc channel enable 0x%X\n",
137 module, (uint32_t) (dmacHw_REG_MISC_CH_ENABLE(module)));
138 (*fpPrint) ("Module %d: misc ID 0x%X\n",
139 module, (uint32_t) (dmacHw_REG_MISC_ID(module)));
140 (*fpPrint) ("Module %d: misc test 0x%X\n",
141 module, (uint32_t) (dmacHw_REG_MISC_TEST(module)));
142
143 if (channel == -1) {
144 for (chan = 0; chan < 8; chan++) {
145 (*fpPrint)
146 ("--------------------------------------------------\n");
147 (*fpPrint)
148 ("Module %d: Channel %d Source 0x%X\n",
149 module, chan,
150 (uint32_t) (dmacHw_REG_SAR(module, chan)));
151 (*fpPrint)
152 ("Module %d: Channel %d Destination 0x%X\n",
153 module, chan,
154 (uint32_t) (dmacHw_REG_DAR(module, chan)));
155 (*fpPrint)
156 ("Module %d: Channel %d LLP 0x%X\n",
157 module, chan,
158 (uint32_t) (dmacHw_REG_LLP(module, chan)));
159 (*fpPrint)
160 ("Module %d: Channel %d Control (LO) 0x%X\n",
161 module, chan,
162 (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
163 (*fpPrint)
164 ("Module %d: Channel %d Control (HI) 0x%X\n",
165 module, chan,
166 (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
167 (*fpPrint)
168 ("Module %d: Channel %d Source Stats 0x%X\n",
169 module, chan,
170 (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
171 (*fpPrint)
172 ("Module %d: Channel %d Dest Stats 0x%X\n",
173 module, chan,
174 (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
175 (*fpPrint)
176 ("Module %d: Channel %d Source Stats Addr 0x%X\n",
177 module, chan,
178 (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
179 (*fpPrint)
180 ("Module %d: Channel %d Dest Stats Addr 0x%X\n",
181 module, chan,
182 (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
183 (*fpPrint)
184 ("Module %d: Channel %d Config (LO) 0x%X\n",
185 module, chan,
186 (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
187 (*fpPrint)
188 ("Module %d: Channel %d Config (HI) 0x%X\n",
189 module, chan,
190 (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
191 }
192 } else {
193 chan = channel;
194 (*fpPrint)
195 ("--------------------------------------------------\n");
196 (*fpPrint)
197 ("Module %d: Channel %d Source 0x%X\n",
198 module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan)));
199 (*fpPrint)
200 ("Module %d: Channel %d Destination 0x%X\n",
201 module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan)));
202 (*fpPrint)
203 ("Module %d: Channel %d LLP 0x%X\n",
204 module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan)));
205 (*fpPrint)
206 ("Module %d: Channel %d Control (LO) 0x%X\n",
207 module, chan,
208 (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
209 (*fpPrint)
210 ("Module %d: Channel %d Control (HI) 0x%X\n",
211 module, chan,
212 (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
213 (*fpPrint)
214 ("Module %d: Channel %d Source Stats 0x%X\n",
215 module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
216 (*fpPrint)
217 ("Module %d: Channel %d Dest Stats 0x%X\n",
218 module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
219 (*fpPrint)
220 ("Module %d: Channel %d Source Stats Addr 0x%X\n",
221 module, chan,
222 (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
223 (*fpPrint)
224 ("Module %d: Channel %d Dest Stats Addr 0x%X\n",
225 module, chan,
226 (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
227 (*fpPrint)
228 ("Module %d: Channel %d Config (LO) 0x%X\n",
229 module, chan,
230 (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
231 (*fpPrint)
232 ("Module %d: Channel %d Config (HI) 0x%X\n",
233 module, chan,
234 (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
235 }
236}
237
238/****************************************************************************/
239/**
240* @brief Helper function to display descriptor ring
241*
242* @return void
243*
244*
245* @note
246* None
247*/
248/****************************************************************************/
249static void DisplayDescRing(void *pDescriptor, /* [ IN ] Descriptor buffer */
250 int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */
251 ) {
252 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
253 dmacHw_DESC_t *pStart;
254
255 if (pRing->pHead == NULL) {
256 return;
257 }
258
259 pStart = pRing->pHead;
260
261 while ((dmacHw_DESC_t *) pStart->llp != pRing->pHead) {
262 if (pStart == pRing->pHead) {
263 (*fpPrint) ("Head\n");
264 }
265 if (pStart == pRing->pTail) {
266 (*fpPrint) ("Tail\n");
267 }
268 if (pStart == pRing->pProg) {
269 (*fpPrint) ("Prog\n");
270 }
271 if (pStart == pRing->pEnd) {
272 (*fpPrint) ("End\n");
273 }
274 if (pStart == pRing->pFree) {
275 (*fpPrint) ("Free\n");
276 }
277 (*fpPrint) ("0x%X:\n", (uint32_t) pStart);
278 (*fpPrint) ("sar 0x%0X\n", pStart->sar);
279 (*fpPrint) ("dar 0x%0X\n", pStart->dar);
280 (*fpPrint) ("llp 0x%0X\n", pStart->llp);
281 (*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo);
282 (*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi);
283 (*fpPrint) ("sstat 0x%0X\n", pStart->sstat);
284 (*fpPrint) ("dstat 0x%0X\n", pStart->dstat);
285 (*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl);
286
287 pStart = (dmacHw_DESC_t *) pStart->llp;
288 }
289 if (pStart == pRing->pHead) {
290 (*fpPrint) ("Head\n");
291 }
292 if (pStart == pRing->pTail) {
293 (*fpPrint) ("Tail\n");
294 }
295 if (pStart == pRing->pProg) {
296 (*fpPrint) ("Prog\n");
297 }
298 if (pStart == pRing->pEnd) {
299 (*fpPrint) ("End\n");
300 }
301 if (pStart == pRing->pFree) {
302 (*fpPrint) ("Free\n");
303 }
304 (*fpPrint) ("0x%X:\n", (uint32_t) pStart);
305 (*fpPrint) ("sar 0x%0X\n", pStart->sar);
306 (*fpPrint) ("dar 0x%0X\n", pStart->dar);
307 (*fpPrint) ("llp 0x%0X\n", pStart->llp);
308 (*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo);
309 (*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi);
310 (*fpPrint) ("sstat 0x%0X\n", pStart->sstat);
311 (*fpPrint) ("dstat 0x%0X\n", pStart->dstat);
312 (*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl);
313}
314
315/****************************************************************************/
316/**
317* @brief Check if DMA channel is the flow controller
318*
319* @return 1 : If DMA is a flow controler
320* 0 : Peripheral is the flow controller
321*
322* @note
323* None
324*/
325/****************************************************************************/
326static inline int DmaIsFlowController(void *pDescriptor /* [ IN ] Descriptor buffer */
327 ) {
328 uint32_t ttfc =
329 (dmacHw_GET_DESC_RING(pDescriptor))->pTail->ctl.
330 lo & dmacHw_REG_CTL_TTFC_MASK;
331
332 switch (ttfc) {
333 case dmacHw_REG_CTL_TTFC_MM_DMAC:
334 case dmacHw_REG_CTL_TTFC_MP_DMAC:
335 case dmacHw_REG_CTL_TTFC_PM_DMAC:
336 case dmacHw_REG_CTL_TTFC_PP_DMAC:
337 return 1;
338 }
339
340 return 0;
341}
342
343/****************************************************************************/
344/**
345* @brief Overwrites data length in the descriptor
346*
347* This function overwrites data length in the descriptor
348*
349*
350* @return void
351*
352* @note
353* This is only used for PCM channel
354*/
355/****************************************************************************/
356void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
357 void *pDescriptor, /* [ IN ] Descriptor buffer */
358 size_t dataLen /* [ IN ] Data length in bytes */
359 ) {
360 dmacHw_DESC_t *pProg;
361 dmacHw_DESC_t *pHead;
362 int srcTs = 0;
363 int srcTrSize = 0;
364
365 pHead = (dmacHw_GET_DESC_RING(pDescriptor))->pHead;
366 pProg = pHead;
367
368 srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
369 srcTs = dataLen / srcTrSize;
370 do {
371 pProg->ctl.hi = srcTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
372 pProg = (dmacHw_DESC_t *) pProg->llp;
373 } while (pProg != pHead);
374}
375
376/****************************************************************************/
377/**
378* @brief Clears the interrupt
379*
380* This function clears the DMA channel specific interrupt
381*
382*
383* @return void
384*
385* @note
386* Must be called under the context of ISR
387*/
388/****************************************************************************/
389void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
390 ) {
391 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
392
393 dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
394 dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
395 dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
396}
397
398/****************************************************************************/
399/**
400* @brief Returns the cause of channel specific DMA interrupt
401*
402* This function returns the cause of interrupt
403*
404* @return Interrupt status, each bit representing a specific type of interrupt
405*
406* @note
407* Should be called under the context of ISR
408*/
409/****************************************************************************/
410dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
411 ) {
412 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
413 dmacHw_INTERRUPT_STATUS_e status = dmacHw_INTERRUPT_STATUS_NONE;
414
415 if (dmacHw_REG_INT_STAT_TRAN(pCblk->module) &
416 ((0x00000001 << pCblk->channel))) {
417 status |= dmacHw_INTERRUPT_STATUS_TRANS;
418 }
419 if (dmacHw_REG_INT_STAT_BLOCK(pCblk->module) &
420 ((0x00000001 << pCblk->channel))) {
421 status |= dmacHw_INTERRUPT_STATUS_BLOCK;
422 }
423 if (dmacHw_REG_INT_STAT_ERROR(pCblk->module) &
424 ((0x00000001 << pCblk->channel))) {
425 status |= dmacHw_INTERRUPT_STATUS_ERROR;
426 }
427
428 return status;
429}
430
431/****************************************************************************/
432/**
433* @brief Indentifies a DMA channel causing interrupt
434*
435* This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e
436*
437* @return NULL : No channel causing DMA interrupt
438* ! NULL : Handle to a channel causing DMA interrupt
439* @note
440* dmacHw_clearInterrupt() must be called with a valid handle after calling this function
441*/
442/****************************************************************************/
443dmacHw_HANDLE_t dmacHw_getInterruptSource(void)
444{
445 uint32_t i;
446
447 for (i = 0; i < dmaChannelCount_0 + dmaChannelCount_1; i++) {
448 if ((dmacHw_REG_INT_STAT_TRAN(dmacHw_gCblk[i].module) &
449 ((0x00000001 << dmacHw_gCblk[i].channel)))
450 || (dmacHw_REG_INT_STAT_BLOCK(dmacHw_gCblk[i].module) &
451 ((0x00000001 << dmacHw_gCblk[i].channel)))
452 || (dmacHw_REG_INT_STAT_ERROR(dmacHw_gCblk[i].module) &
453 ((0x00000001 << dmacHw_gCblk[i].channel)))
454 ) {
455 return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[i]);
456 }
457 }
458 return dmacHw_CBLK_TO_HANDLE(NULL);
459}
460
461/****************************************************************************/
462/**
463* @brief Estimates number of descriptor needed to perform certain DMA transfer
464*
465*
466* @return On failure : -1
467* On success : Number of descriptor count
468*
469*
470*/
471/****************************************************************************/
472int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
473 void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
474 void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
475 size_t dataLen /* [ IN ] Data length in bytes */
476 ) {
477 int srcTs = 0;
478 int oddSize = 0;
479 int descCount = 0;
480 int dstTrSize = 0;
481 int srcTrSize = 0;
482 uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
483 dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
484 dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
485
486 dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
487 srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
488
489 /* Skip Tx if buffer is NULL or length is unknown */
490 if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
491 /* Do not initiate transfer */
492 return -1;
493 }
494
495 /* Ensure scatter and gather are transaction aligned */
496 if (pConfig->srcGatherWidth % srcTrSize
497 || pConfig->dstScatterWidth % dstTrSize) {
498 return -1;
499 }
500
501 /*
502 Background 1: DMAC can not perform DMA if source and destination addresses are
503 not properly aligned with the channel's transaction width. So, for successful
504 DMA transfer, transaction width must be set according to the alignment of the
505 source and destination address.
506 */
507
508 /* Adjust destination transaction width if destination address is not aligned properly */
509 dstTrWidth = pConfig->dstMaxTransactionWidth;
510 while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
511 dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
512 dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
513 }
514
515 /* Adjust source transaction width if source address is not aligned properly */
516 srcTrWidth = pConfig->srcMaxTransactionWidth;
517 while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
518 srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
519 srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
520 }
521
522 /* Find the maximum transaction per descriptor */
523 if (pConfig->maxDataPerBlock
524 && ((pConfig->maxDataPerBlock / srcTrSize) <
525 dmacHw_MAX_BLOCKSIZE)) {
526 maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
527 }
528
529 /* Find number of source transactions needed to complete the DMA transfer */
530 srcTs = dataLen / srcTrSize;
531 /* Find the odd number of bytes that need to be transferred as single byte transaction width */
532 if (srcTs && (dstTrSize > srcTrSize)) {
533 oddSize = dataLen % dstTrSize;
534 /* Adjust source transaction count due to "oddSize" */
535 srcTs = srcTs - (oddSize / srcTrSize);
536 } else {
537 oddSize = dataLen % srcTrSize;
538 }
539 /* Adjust "descCount" due to "oddSize" */
540 if (oddSize) {
541 descCount++;
542 }
543
544 /* Find the number of descriptor needed for total "srcTs" */
545 if (srcTs) {
546 descCount += ((srcTs - 1) / maxBlockSize) + 1;
547 }
548
549 return descCount;
550}
551
552/****************************************************************************/
553/**
554* @brief Check the existance of pending descriptor
555*
556* This function confirmes if there is any pending descriptor in the chain
557* to program the channel
558*
559* @return 1 : Channel need to be programmed with pending descriptor
560* 0 : No more pending descriptor to programe the channel
561*
562* @note
563* - This function should be called from ISR in case there are pending
564* descriptor to program the channel.
565*
566* Example:
567*
568* dmac_isr ()
569* {
570* ...
571* if (dmacHw_descriptorPending (handle))
572* {
573* dmacHw_initiateTransfer (handle);
574* }
575* }
576*
577*/
578/****************************************************************************/
579uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
580 void *pDescriptor /* [ IN ] Descriptor buffer */
581 ) {
582 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
583 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
584
585 /* Make sure channel is not busy */
586 if (!CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
587 /* Check if pEnd is not processed */
588 if (pRing->pEnd) {
589 /* Something left for processing */
590 return 1;
591 }
592 }
593 return 0;
594}
595
596/****************************************************************************/
597/**
598* @brief Program channel register to stop transfer
599*
600* Ensures the channel is not doing any transfer after calling this function
601*
602* @return void
603*
604*/
605/****************************************************************************/
606void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
607 ) {
608 dmacHw_CBLK_t *pCblk;
609
610 pCblk = dmacHw_HANDLE_TO_CBLK(handle);
611
612 /* Stop the channel */
613 dmacHw_DMA_STOP(pCblk->module, pCblk->channel);
614}
615
616/****************************************************************************/
617/**
618* @brief Deallocates source or destination memory, allocated
619*
620* This function can be called to deallocate data memory that was DMAed successfully
621*
622* @return On failure : -1
623* On success : Number of buffer freed
624*
625* @note
626* This function will be called ONLY, when source OR destination address is pointing
627* to dynamic memory
628*/
629/****************************************************************************/
630int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
631 void *pDescriptor, /* [ IN ] Descriptor buffer */
632 void (*fpFree) (void *) /* [ IN ] Function pointer to free data memory */
633 ) {
634 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
635 uint32_t count = 0;
636
637 if (fpFree == NULL) {
638 return -1;
639 }
640
641 while ((pRing->pFree != pRing->pTail)
642 && (pRing->pFree->ctl.lo & dmacHw_DESC_FREE)) {
643 if (pRing->pFree->devCtl == dmacHw_FREE_USER_MEMORY) {
644 /* Identify, which memory to free */
645 if (dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
646 (*fpFree) ((void *)pRing->pFree->dar);
647 } else {
648 /* Destination was a peripheral */
649 (*fpFree) ((void *)pRing->pFree->sar);
650 }
651 /* Unmark user memory to indicate it is freed */
652 pRing->pFree->devCtl = ~dmacHw_FREE_USER_MEMORY;
653 }
654 dmacHw_NEXT_DESC(pRing, pFree);
655
656 count++;
657 }
658
659 return count;
660}
661
662/****************************************************************************/
663/**
664* @brief Prepares descriptor ring, when source peripheral working as a flow controller
665*
666* This function will update the discriptor ring by allocating buffers, when source peripheral
667* has to work as a flow controller to transfer data from:
668* - Peripheral to memory.
669*
670* @return On failure : -1
671* On success : Number of descriptor updated
672*
673*
674* @note
675* Channel must be configured for peripheral to memory transfer
676*
677*/
678/****************************************************************************/
679int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
680 dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
681 void *pDescriptor, /* [ IN ] Descriptor buffer */
682 uint32_t srcAddr, /* [ IN ] Source peripheral address */
683 void *(*fpAlloc) (int len), /* [ IN ] Function pointer that provides destination memory */
684 int len, /* [ IN ] Number of bytes "fpAlloc" will allocate for destination */
685 int num /* [ IN ] Number of descriptor to set */
686 ) {
687 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
688 dmacHw_DESC_t *pProg = NULL;
689 dmacHw_DESC_t *pLast = NULL;
690 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
691 uint32_t dstAddr;
692 uint32_t controlParam;
693 int i;
694
695 dmacHw_ASSERT(pConfig->transferType ==
696 dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM);
697
698 if (num > pRing->num) {
699 return -1;
700 }
701
702 pLast = pRing->pEnd; /* Last descriptor updated */
703 pProg = pRing->pHead; /* First descriptor in the new list */
704
705 controlParam = pConfig->srcUpdate |
706 pConfig->dstUpdate |
707 pConfig->srcMaxTransactionWidth |
708 pConfig->dstMaxTransactionWidth |
709 pConfig->srcMasterInterface |
710 pConfig->dstMasterInterface |
711 pConfig->srcMaxBurstWidth |
712 pConfig->dstMaxBurstWidth |
713 dmacHw_REG_CTL_TTFC_PM_PERI |
714 dmacHw_REG_CTL_LLP_DST_EN |
715 dmacHw_REG_CTL_LLP_SRC_EN | dmacHw_REG_CTL_INT_EN;
716
717 for (i = 0; i < num; i++) {
718 /* Allocate Rx buffer only for idle descriptor */
719 if (((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) ||
720 ((dmacHw_DESC_t *) pRing->pHead->llp == pRing->pTail)
721 ) {
722 /* Rx descriptor is not idle */
723 break;
724 }
725 /* Set source address */
726 pRing->pHead->sar = srcAddr;
727 if (fpAlloc) {
728 /* Allocate memory for buffer in descriptor */
729 dstAddr = (uint32_t) (*fpAlloc) (len);
730 /* Check the destination address */
731 if (dstAddr == 0) {
732 if (i == 0) {
733 /* Not a single descriptor is available */
734 return -1;
735 }
736 break;
737 }
738 /* Set destination address */
739 pRing->pHead->dar = dstAddr;
740 }
741 /* Set control information */
742 pRing->pHead->ctl.lo = controlParam;
743 /* Use "devCtl" to mark the memory that need to be freed later */
744 pRing->pHead->devCtl = dmacHw_FREE_USER_MEMORY;
745 /* Descriptor is now owned by the channel */
746 pRing->pHead->ctl.hi = 0;
747 /* Remember the descriptor last updated */
748 pRing->pEnd = pRing->pHead;
749 /* Update next descriptor */
750 dmacHw_NEXT_DESC(pRing, pHead);
751 }
752
753 /* Mark the end of the list */
754 pRing->pEnd->ctl.lo &=
755 ~(dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN);
756 /* Connect the list */
757 if (pLast != pProg) {
758 pLast->ctl.lo |=
759 dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN;
760 }
761 /* Mark the descriptors are updated */
762 pCblk->descUpdated = 1;
763 if (!pCblk->varDataStarted) {
764 /* LLP must be pointing to the first descriptor */
765 dmacHw_SET_LLP(pCblk->module, pCblk->channel,
766 (uint32_t) pProg - pRing->virt2PhyOffset);
767 /* Channel, handling variable data started */
768 pCblk->varDataStarted = 1;
769 }
770
771 return i;
772}
773
774/****************************************************************************/
775/**
776* @brief Read data DMAed to memory
777*
778* This function will read data that has been DMAed to memory while transfering from:
779* - Memory to memory
780* - Peripheral to memory
781*
782* @param handle -
783* @param ppBbuf -
784* @param pLen -
785*
786* @return 0 - No more data is available to read
787* 1 - More data might be available to read
788*
789*/
790/****************************************************************************/
791int dmacHw_readTransferredData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
792 dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
793 void *pDescriptor, /* [ IN ] Descriptor buffer */
794 void **ppBbuf, /* [ OUT ] Data received */
795 size_t *pLlen /* [ OUT ] Length of the data received */
796 ) {
797 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
798
799 (void)handle;
800
801 if (pConfig->transferMode != dmacHw_TRANSFER_MODE_CONTINUOUS) {
802 if (((pRing->pTail->ctl.hi & dmacHw_DESC_FREE) == 0) ||
803 (pRing->pTail == pRing->pHead)
804 ) {
805 /* No receive data available */
806 *ppBbuf = (char *)NULL;
807 *pLlen = 0;
808
809 return 0;
810 }
811 }
812
813 /* Return read buffer and length */
814 *ppBbuf = (char *)pRing->pTail->dar;
815
816 /* Extract length of the received data */
817 if (DmaIsFlowController(pDescriptor)) {
818 uint32_t srcTrSize = 0;
819
820 switch (pRing->pTail->ctl.lo & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) {
821 case dmacHw_REG_CTL_SRC_TR_WIDTH_8:
822 srcTrSize = 1;
823 break;
824 case dmacHw_REG_CTL_SRC_TR_WIDTH_16:
825 srcTrSize = 2;
826 break;
827 case dmacHw_REG_CTL_SRC_TR_WIDTH_32:
828 srcTrSize = 4;
829 break;
830 case dmacHw_REG_CTL_SRC_TR_WIDTH_64:
831 srcTrSize = 8;
832 break;
833 default:
834 dmacHw_ASSERT(0);
835 }
836 /* Calculate length from the block size */
837 *pLlen =
838 (pRing->pTail->ctl.hi & dmacHw_REG_CTL_BLOCK_TS_MASK) *
839 srcTrSize;
840 } else {
841 /* Extract length from the source peripheral */
842 *pLlen = pRing->pTail->sstat;
843 }
844
845 /* Advance tail to next descriptor */
846 dmacHw_NEXT_DESC(pRing, pTail);
847
848 return 1;
849}
850
851/****************************************************************************/
852/**
853* @brief Set descriptor carrying control information
854*
855* This function will be used to send specific control information to the device
856* using the DMA channel
857*
858*
859* @return -1 - On failure
860* 0 - On success
861*
862* @note
863* None
864*/
865/****************************************************************************/
866int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
867 void *pDescriptor, /* [ IN ] Descriptor buffer */
868 uint32_t ctlAddress, /* [ IN ] Address of the device control register */
869 uint32_t control /* [ IN ] Device control information */
870 ) {
871 dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
872
873 if (ctlAddress == 0) {
874 return -1;
875 }
876
877 /* Check the availability of descriptors in the ring */
878 if ((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) {
879 return -1;
880 }
881 /* Set control information */
882 pRing->pHead->devCtl = control;
883 /* Set source and destination address */
884 pRing->pHead->sar = (uint32_t) &pRing->pHead->devCtl;
885 pRing->pHead->dar = ctlAddress;
886 /* Set control parameters */
887 if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
888 pRing->pHead->ctl.lo = pConfig->transferType |
889 dmacHw_SRC_ADDRESS_UPDATE_MODE_INC |
890 dmacHw_DST_ADDRESS_UPDATE_MODE_INC |
891 dmacHw_SRC_TRANSACTION_WIDTH_32 |
892 pConfig->dstMaxTransactionWidth |
893 dmacHw_SRC_BURST_WIDTH_0 |
894 dmacHw_DST_BURST_WIDTH_0 |
895 pConfig->srcMasterInterface |
896 pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
897 } else {
898 uint32_t transferType = 0;
899 switch (pConfig->transferType) {
900 case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
901 transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
902 break;
903 case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
904 transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
905 break;
906 default:
907 dmacHw_ASSERT(0);
908 }
909 pRing->pHead->ctl.lo = transferType |
910 dmacHw_SRC_ADDRESS_UPDATE_MODE_INC |
911 dmacHw_DST_ADDRESS_UPDATE_MODE_INC |
912 dmacHw_SRC_TRANSACTION_WIDTH_32 |
913 pConfig->dstMaxTransactionWidth |
914 dmacHw_SRC_BURST_WIDTH_0 |
915 dmacHw_DST_BURST_WIDTH_0 |
916 pConfig->srcMasterInterface |
917 pConfig->dstMasterInterface |
918 pConfig->flowControler | dmacHw_REG_CTL_INT_EN;
919 }
920
921 /* Set block transaction size to one 32 bit transaction */
922 pRing->pHead->ctl.hi = dmacHw_REG_CTL_BLOCK_TS_MASK & 1;
923
924 /* Remember the descriptor to initialize the registers */
925 if (pRing->pProg == dmacHw_DESC_INIT) {
926 pRing->pProg = pRing->pHead;
927 }
928 pRing->pEnd = pRing->pHead;
929
930 /* Advance the descriptor */
931 dmacHw_NEXT_DESC(pRing, pHead);
932
933 /* Update Tail pointer if destination is a peripheral */
934 if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
935 pRing->pTail = pRing->pHead;
936 }
937 return 0;
938}
939
940/****************************************************************************/
941/**
942* @brief Sets channel specific user data
943*
944* This function associates user data to a specif DMA channel
945*
946*/
947/****************************************************************************/
948void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
949 void *userData /* [ IN ] User data */
950 ) {
951 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
952
953 pCblk->userData = userData;
954}
955
956/****************************************************************************/
957/**
958* @brief Gets channel specific user data
959*
960* This function returns user data specific to a DMA channel
961*
962* @return user data
963*/
964/****************************************************************************/
965void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
966 ) {
967 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
968
969 return pCblk->userData;
970}
971
972/****************************************************************************/
973/**
974* @brief Resets descriptor control information
975*
976* @return void
977*/
978/****************************************************************************/
979void dmacHw_resetDescriptorControl(void *pDescriptor /* [ IN ] Descriptor buffer */
980 ) {
981 int i;
982 dmacHw_DESC_RING_t *pRing;
983 dmacHw_DESC_t *pDesc;
984
985 pRing = dmacHw_GET_DESC_RING(pDescriptor);
986 pDesc = pRing->pHead;
987
988 for (i = 0; i < pRing->num; i++) {
989 /* Mark descriptor is ready to use */
990 pDesc->ctl.hi = dmacHw_DESC_FREE;
991 /* Look into next link list item */
992 pDesc++;
993 }
994 pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
995 pRing->pProg = dmacHw_DESC_INIT;
996}
997
998/****************************************************************************/
999/**
1000* @brief Displays channel specific registers and other control parameters
1001*
1002* @return void
1003*
1004*
1005* @note
1006* None
1007*/
1008/****************************************************************************/
1009void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
1010 void *pDescriptor, /* [ IN ] Descriptor buffer */
1011 int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
1012 ) {
1013 dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
1014
1015 DisplayRegisterContents(pCblk->module, pCblk->channel, fpPrint);
1016 DisplayDescRing(pDescriptor, fpPrint);
1017}
diff --git a/arch/arm/mach-bcmring/csp/tmr/Makefile b/arch/arm/mach-bcmring/csp/tmr/Makefile
new file mode 100644
index 000000000000..244a61ab7697
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/tmr/Makefile
@@ -0,0 +1 @@
obj-y += tmrHw.o
diff --git a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c
new file mode 100644
index 000000000000..5c1c9a0e5ed2
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c
@@ -0,0 +1,576 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file tmrHw.c
18*
19* @brief Low level Timer driver routines
20*
21* @note
22*
23* These routines provide basic timer functionality only.
24*/
25/****************************************************************************/
26
27/* ---- Include Files ---------------------------------------------------- */
28
29#include <csp/errno.h>
30#include <csp/stdint.h>
31
32#include <csp/tmrHw.h>
33#include <mach/csp/tmrHw_reg.h>
34
35#define tmrHw_ASSERT(a) if (!(a)) *(char *)0 = 0
36#define tmrHw_MILLISEC_PER_SEC (1000)
37
38#define tmrHw_LOW_1_RESOLUTION_COUNT (tmrHw_LOW_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
39#define tmrHw_LOW_1_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_1_RESOLUTION_COUNT)
40#define tmrHw_LOW_16_RESOLUTION_COUNT (tmrHw_LOW_1_RESOLUTION_COUNT / 16)
41#define tmrHw_LOW_16_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_16_RESOLUTION_COUNT)
42#define tmrHw_LOW_256_RESOLUTION_COUNT (tmrHw_LOW_1_RESOLUTION_COUNT / 256)
43#define tmrHw_LOW_256_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_256_RESOLUTION_COUNT)
44
45#define tmrHw_HIGH_1_RESOLUTION_COUNT (tmrHw_HIGH_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
46#define tmrHw_HIGH_1_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_1_RESOLUTION_COUNT)
47#define tmrHw_HIGH_16_RESOLUTION_COUNT (tmrHw_HIGH_1_RESOLUTION_COUNT / 16)
48#define tmrHw_HIGH_16_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_16_RESOLUTION_COUNT)
49#define tmrHw_HIGH_256_RESOLUTION_COUNT (tmrHw_HIGH_1_RESOLUTION_COUNT / 256)
50#define tmrHw_HIGH_256_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_256_RESOLUTION_COUNT)
51
52static void ResetTimer(tmrHw_ID_t timerId)
53 __attribute__ ((section(".aramtext")));
54static int tmrHw_divide(int num, int denom)
55 __attribute__ ((section(".aramtext")));
56
57/****************************************************************************/
58/**
59* @brief Get timer capability
60*
61* This function returns various capabilities/attributes of a timer
62*
63* @return Capability
64*
65*/
66/****************************************************************************/
67uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
68 tmrHw_CAPABILITY_e capability /* [ IN ] Timer capability */
69) {
70 switch (capability) {
71 case tmrHw_CAPABILITY_CLOCK:
72 return (timerId <=
73 1) ? tmrHw_LOW_RESOLUTION_CLOCK :
74 tmrHw_HIGH_RESOLUTION_CLOCK;
75 case tmrHw_CAPABILITY_RESOLUTION:
76 return 32;
77 default:
78 return 0;
79 }
80 return 0;
81}
82
83/****************************************************************************/
84/**
85* @brief Resets a timer
86*
87* This function initializes timer
88*
89* @return void
90*
91*/
92/****************************************************************************/
93static void ResetTimer(tmrHw_ID_t timerId /* [ IN ] Timer Id */
94) {
95 /* Reset timer */
96 pTmrHw[timerId].LoadValue = 0;
97 pTmrHw[timerId].CurrentValue = 0xFFFFFFFF;
98 pTmrHw[timerId].Control = 0;
99 pTmrHw[timerId].BackgroundLoad = 0;
100 /* Always configure as a 32 bit timer */
101 pTmrHw[timerId].Control |= tmrHw_CONTROL_32BIT;
102 /* Clear interrupt only if raw status interrupt is set */
103 if (pTmrHw[timerId].RawInterruptStatus) {
104 pTmrHw[timerId].InterruptClear = 0xFFFFFFFF;
105 }
106}
107
108/****************************************************************************/
109/**
110* @brief Sets counter value for an interval in ms
111*
112* @return On success: Effective counter value set
113* On failure: 0
114*
115*/
116/****************************************************************************/
117static tmrHw_INTERVAL_t SetTimerPeriod(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
118 tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */
119) {
120 uint32_t scale = 0;
121 uint32_t count = 0;
122
123 if (timerId == 0 || timerId == 1) {
124 if (msec <= tmrHw_LOW_1_MAX_MILLISEC) {
125 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
126 scale = tmrHw_LOW_1_RESOLUTION_COUNT;
127 } else if (msec <= tmrHw_LOW_16_MAX_MILLISEC) {
128 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
129 scale = tmrHw_LOW_16_RESOLUTION_COUNT;
130 } else if (msec <= tmrHw_LOW_256_MAX_MILLISEC) {
131 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
132 scale = tmrHw_LOW_256_RESOLUTION_COUNT;
133 } else {
134 return 0;
135 }
136
137 count = msec * scale;
138 /* Set counter value */
139 pTmrHw[timerId].LoadValue = count;
140 pTmrHw[timerId].BackgroundLoad = count;
141
142 } else if (timerId == 2 || timerId == 3) {
143 if (msec <= tmrHw_HIGH_1_MAX_MILLISEC) {
144 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
145 scale = tmrHw_HIGH_1_RESOLUTION_COUNT;
146 } else if (msec <= tmrHw_HIGH_16_MAX_MILLISEC) {
147 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
148 scale = tmrHw_HIGH_16_RESOLUTION_COUNT;
149 } else if (msec <= tmrHw_HIGH_256_MAX_MILLISEC) {
150 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
151 scale = tmrHw_HIGH_256_RESOLUTION_COUNT;
152 } else {
153 return 0;
154 }
155
156 count = msec * scale;
157 /* Set counter value */
158 pTmrHw[timerId].LoadValue = count;
159 pTmrHw[timerId].BackgroundLoad = count;
160 }
161 return count / scale;
162}
163
164/****************************************************************************/
165/**
166* @brief Configures a periodic timer in terms of timer interrupt rate
167*
168* This function initializes a periodic timer to generate specific number of
169* timer interrupt per second
170*
171* @return On success: Effective timer frequency
172* On failure: 0
173*
174*/
175/****************************************************************************/
176tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
177 tmrHw_RATE_t rate /* [ IN ] Number of timer interrupt per second */
178) {
179 uint32_t resolution = 0;
180 uint32_t count = 0;
181 ResetTimer(timerId);
182
183 /* Set timer mode periodic */
184 pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
185 pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
186 /* Set timer in highest resolution */
187 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
188
189 if (rate && (timerId == 0 || timerId == 1)) {
190 if (rate > tmrHw_LOW_RESOLUTION_CLOCK) {
191 return 0;
192 }
193 resolution = tmrHw_LOW_RESOLUTION_CLOCK;
194 } else if (rate && (timerId == 2 || timerId == 3)) {
195 if (rate > tmrHw_HIGH_RESOLUTION_CLOCK) {
196 return 0;
197 } else {
198 resolution = tmrHw_HIGH_RESOLUTION_CLOCK;
199 }
200 } else {
201 return 0;
202 }
203 /* Find the counter value */
204 count = resolution / rate;
205 /* Set counter value */
206 pTmrHw[timerId].LoadValue = count;
207 pTmrHw[timerId].BackgroundLoad = count;
208
209 return resolution / count;
210}
211
212/****************************************************************************/
213/**
214* @brief Configures a periodic timer to generate timer interrupt after
215* certain time interval
216*
217* This function initializes a periodic timer to generate timer interrupt
218* after every time interval in millisecond
219*
220* @return On success: Effective interval set in milli-second
221* On failure: 0
222*
223*/
224/****************************************************************************/
225tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
226 tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */
227) {
228 ResetTimer(timerId);
229
230 /* Set timer mode periodic */
231 pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
232 pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
233
234 return SetTimerPeriod(timerId, msec);
235}
236
237/****************************************************************************/
238/**
239* @brief Configures a periodic timer to generate timer interrupt just once
240* after certain time interval
241*
242* This function initializes a periodic timer to generate a single ticks after
243* certain time interval in millisecond
244*
245* @return On success: Effective interval set in milli-second
246* On failure: 0
247*
248*/
249/****************************************************************************/
250tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
251 tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */
252) {
253 ResetTimer(timerId);
254
255 /* Set timer mode oneshot */
256 pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
257 pTmrHw[timerId].Control |= tmrHw_CONTROL_ONESHOT;
258
259 return SetTimerPeriod(timerId, msec);
260}
261
262/****************************************************************************/
263/**
264* @brief Configures a timer to run as a free running timer
265*
266* This function initializes a timer to run as a free running timer
267*
268* @return Timer resolution (count / sec)
269*
270*/
271/****************************************************************************/
272tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
273 uint32_t divider /* [ IN ] Dividing the clock frequency */
274) {
275 uint32_t scale = 0;
276
277 ResetTimer(timerId);
278 /* Set timer as free running mode */
279 pTmrHw[timerId].Control &= ~tmrHw_CONTROL_PERIODIC;
280 pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
281
282 if (divider >= 64) {
283 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
284 scale = 256;
285 } else if (divider >= 8) {
286 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
287 scale = 16;
288 } else {
289 pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
290 scale = 1;
291 }
292
293 if (timerId == 0 || timerId == 1) {
294 return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, scale);
295 } else if (timerId == 2 || timerId == 3) {
296 return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, scale);
297 }
298
299 return 0;
300}
301
302/****************************************************************************/
303/**
304* @brief Starts a timer
305*
306* This function starts a preconfigured timer
307*
308* @return -1 - On Failure
309* 0 - On Success
310*
311*/
312/****************************************************************************/
313int tmrHw_startTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
314) {
315 pTmrHw[timerId].Control |= tmrHw_CONTROL_TIMER_ENABLE;
316 return 0;
317}
318
319/****************************************************************************/
320/**
321* @brief Stops a timer
322*
323* This function stops a running timer
324*
325* @return -1 - On Failure
326* 0 - On Success
327*
328*/
329/****************************************************************************/
330int tmrHw_stopTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
331) {
332 pTmrHw[timerId].Control &= ~tmrHw_CONTROL_TIMER_ENABLE;
333 return 0;
334}
335
336/****************************************************************************/
337/**
338* @brief Gets current timer count
339*
340* This function returns the current timer value
341*
342* @return Current downcounting timer value
343*
344*/
345/****************************************************************************/
346uint32_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId /* [ IN ] Timer id */
347) {
348 /* return 32 bit timer value */
349 switch (pTmrHw[timerId].Control & tmrHw_CONTROL_MODE_MASK) {
350 case tmrHw_CONTROL_FREE_RUNNING:
351 if (pTmrHw[timerId].CurrentValue) {
352 return tmrHw_MAX_COUNT - pTmrHw[timerId].CurrentValue;
353 }
354 break;
355 case tmrHw_CONTROL_PERIODIC:
356 case tmrHw_CONTROL_ONESHOT:
357 return pTmrHw[timerId].BackgroundLoad -
358 pTmrHw[timerId].CurrentValue;
359 }
360 return 0;
361}
362
363/****************************************************************************/
364/**
365* @brief Gets timer count rate
366*
367* This function returns the number of counts per second
368*
369* @return Count rate
370*
371*/
372/****************************************************************************/
373tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId /* [ IN ] Timer id */
374) {
375 uint32_t divider = 0;
376
377 switch (pTmrHw[timerId].Control & tmrHw_CONTROL_PRESCALE_MASK) {
378 case tmrHw_CONTROL_PRESCALE_1:
379 divider = 1;
380 break;
381 case tmrHw_CONTROL_PRESCALE_16:
382 divider = 16;
383 break;
384 case tmrHw_CONTROL_PRESCALE_256:
385 divider = 256;
386 break;
387 default:
388 tmrHw_ASSERT(0);
389 }
390
391 if (timerId == 0 || timerId == 1) {
392 return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, divider);
393 } else {
394 return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, divider);
395 }
396 return 0;
397}
398
399/****************************************************************************/
400/**
401* @brief Enables timer interrupt
402*
403* This function enables the timer interrupt
404*
405* @return N/A
406*
407*/
408/****************************************************************************/
409void tmrHw_enableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
410) {
411 pTmrHw[timerId].Control |= tmrHw_CONTROL_INTERRUPT_ENABLE;
412}
413
414/****************************************************************************/
415/**
416* @brief Disables timer interrupt
417*
418* This function disable the timer interrupt
419*
420* @return N/A
421*
422*/
423/****************************************************************************/
424void tmrHw_disableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
425) {
426 pTmrHw[timerId].Control &= ~tmrHw_CONTROL_INTERRUPT_ENABLE;
427}
428
429/****************************************************************************/
430/**
431* @brief Clears the interrupt
432*
433* This function clears the timer interrupt
434*
435* @return N/A
436*
437* @note
438* Must be called under the context of ISR
439*/
440/****************************************************************************/
441void tmrHw_clearInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
442) {
443 pTmrHw[timerId].InterruptClear = 0x1;
444}
445
446/****************************************************************************/
447/**
448* @brief Gets the interrupt status
449*
450* This function returns timer interrupt status
451*
452* @return Interrupt status
453*/
454/****************************************************************************/
455tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId /* [ IN ] Timer id */
456) {
457 if (pTmrHw[timerId].InterruptStatus) {
458 return tmrHw_INTERRUPT_STATUS_SET;
459 } else {
460 return tmrHw_INTERRUPT_STATUS_UNSET;
461 }
462}
463
464/****************************************************************************/
465/**
466* @brief Indentifies a timer causing interrupt
467*
468* This functions returns a timer causing interrupt
469*
470* @return 0xFFFFFFFF : No timer causing an interrupt
471* ! 0xFFFFFFFF : timer causing an interrupt
472* @note
473* tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
474*/
475/****************************************************************************/
476tmrHw_ID_t tmrHw_getInterruptSource(void /* void */
477) {
478 int i;
479
480 for (i = 0; i < tmrHw_TIMER_NUM_COUNT; i++) {
481 if (pTmrHw[i].InterruptStatus) {
482 return i;
483 }
484 }
485
486 return 0xFFFFFFFF;
487}
488
489/****************************************************************************/
490/**
491* @brief Displays specific timer registers
492*
493*
494* @return void
495*
496*/
497/****************************************************************************/
498void tmrHw_printDebugInfo(tmrHw_ID_t timerId, /* [ IN ] Timer id */
499 int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
500) {
501 (*fpPrint) ("Displaying register contents \n\n");
502 (*fpPrint) ("Timer %d: Load value 0x%X\n", timerId,
503 pTmrHw[timerId].LoadValue);
504 (*fpPrint) ("Timer %d: Background load value 0x%X\n", timerId,
505 pTmrHw[timerId].BackgroundLoad);
506 (*fpPrint) ("Timer %d: Control 0x%X\n", timerId,
507 pTmrHw[timerId].Control);
508 (*fpPrint) ("Timer %d: Interrupt clear 0x%X\n", timerId,
509 pTmrHw[timerId].InterruptClear);
510 (*fpPrint) ("Timer %d: Interrupt raw interrupt 0x%X\n", timerId,
511 pTmrHw[timerId].RawInterruptStatus);
512 (*fpPrint) ("Timer %d: Interrupt status 0x%X\n", timerId,
513 pTmrHw[timerId].InterruptStatus);
514}
515
516/****************************************************************************/
517/**
518* @brief Use a timer to perform a busy wait delay for a number of usecs.
519*
520* @return N/A
521*/
522/****************************************************************************/
523void tmrHw_udelay(tmrHw_ID_t timerId, /* [ IN ] Timer id */
524 unsigned long usecs /* [ IN ] usec to delay */
525) {
526 tmrHw_RATE_t usec_tick_rate;
527 tmrHw_COUNT_t start_time;
528 tmrHw_COUNT_t delta_time;
529
530 start_time = tmrHw_GetCurrentCount(timerId);
531 usec_tick_rate = tmrHw_divide(tmrHw_getCountRate(timerId), 1000000);
532 delta_time = usecs * usec_tick_rate;
533
534 /* Busy wait */
535 while (delta_time > (tmrHw_GetCurrentCount(timerId) - start_time))
536 ;
537}
538
539/****************************************************************************/
540/**
541* @brief Local Divide function
542*
543* This function does the divide
544*
545* @return divide value
546*
547*/
548/****************************************************************************/
549static int tmrHw_divide(int num, int denom)
550{
551 int r;
552 int t = 1;
553
554 /* Shift denom and t up to the largest value to optimize algorithm */
555 /* t contains the units of each divide */
556 while ((denom & 0x40000000) == 0) { /* fails if denom=0 */
557 denom = denom << 1;
558 t = t << 1;
559 }
560
561 /* Intialize the result */
562 r = 0;
563
564 do {
565 /* Determine if there exists a positive remainder */
566 if ((num - denom) >= 0) {
567 /* Accumlate t to the result and calculate a new remainder */
568 num = num - denom;
569 r = r + t;
570 }
571 /* Continue to shift denom and shift t down to 0 */
572 denom = denom >> 1;
573 t = t >> 1;
574 } while (t != 0);
575 return r;
576}
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
new file mode 100644
index 000000000000..7b20fccb9d4e
--- /dev/null
+++ b/arch/arm/mach-bcmring/dma.c
@@ -0,0 +1,2321 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dma.c
18*
19* @brief Implements the DMA interface.
20*/
21/****************************************************************************/
22
23/* ---- Include Files ---------------------------------------------------- */
24
25#include <linux/module.h>
26#include <linux/device.h>
27#include <linux/dma-mapping.h>
28#include <linux/interrupt.h>
29#include <linux/irqreturn.h>
30#include <linux/proc_fs.h>
31
32#include <mach/timer.h>
33
34#include <linux/mm.h>
35#include <linux/pfn.h>
36#include <asm/atomic.h>
37#include <mach/dma.h>
38
39/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
40/* especially since dc4 doesn't use kmalloc'd memory. */
41
42#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
43
44/* ---- Public Variables ------------------------------------------------- */
45
46/* ---- Private Constants and Types -------------------------------------- */
47
48#define MAKE_HANDLE(controllerIdx, channelIdx) (((controllerIdx) << 4) | (channelIdx))
49
50#define CONTROLLER_FROM_HANDLE(handle) (((handle) >> 4) & 0x0f)
51#define CHANNEL_FROM_HANDLE(handle) ((handle) & 0x0f)
52
53#define DMA_MAP_DEBUG 0
54
55#if DMA_MAP_DEBUG
56# define DMA_MAP_PRINT(fmt, args...) printk("%s: " fmt, __func__, ## args)
57#else
58# define DMA_MAP_PRINT(fmt, args...)
59#endif
60
61/* ---- Private Variables ------------------------------------------------ */
62
63static DMA_Global_t gDMA;
64static struct proc_dir_entry *gDmaDir;
65
66static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
67static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
68static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
69static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
70
71#include "dma_device.c"
72
73/* ---- Private Function Prototypes -------------------------------------- */
74
75/* ---- Functions ------------------------------------------------------- */
76
77/****************************************************************************/
78/**
79* Displays information for /proc/dma/mem-type
80*/
81/****************************************************************************/
82
83static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
84 int count, int *eof, void *data)
85{
86 int len = 0;
87
88 len += sprintf(buf + len, "dma_map_mem statistics\n");
89 len +=
90 sprintf(buf + len, "coherent: %d\n",
91 atomic_read(&gDmaStatMemTypeCoherent));
92 len +=
93 sprintf(buf + len, "kmalloc: %d\n",
94 atomic_read(&gDmaStatMemTypeKmalloc));
95 len +=
96 sprintf(buf + len, "vmalloc: %d\n",
97 atomic_read(&gDmaStatMemTypeVmalloc));
98 len +=
99 sprintf(buf + len, "user: %d\n",
100 atomic_read(&gDmaStatMemTypeUser));
101
102 return len;
103}
104
105/****************************************************************************/
106/**
107* Displays information for /proc/dma/channels
108*/
109/****************************************************************************/
110
111static int dma_proc_read_channels(char *buf, char **start, off_t offset,
112 int count, int *eof, void *data)
113{
114 int controllerIdx;
115 int channelIdx;
116 int limit = count - 200;
117 int len = 0;
118 DMA_Channel_t *channel;
119
120 if (down_interruptible(&gDMA.lock) < 0) {
121 return -ERESTARTSYS;
122 }
123
124 for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
125 controllerIdx++) {
126 for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
127 channelIdx++) {
128 if (len >= limit) {
129 break;
130 }
131
132 channel =
133 &gDMA.controller[controllerIdx].channel[channelIdx];
134
135 len +=
136 sprintf(buf + len, "%d:%d ", controllerIdx,
137 channelIdx);
138
139 if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
140 0) {
141 len +=
142 sprintf(buf + len, "Dedicated for %s ",
143 DMA_gDeviceAttribute[channel->
144 devType].name);
145 } else {
146 len += sprintf(buf + len, "Shared ");
147 }
148
149 if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) != 0) {
150 len += sprintf(buf + len, "No ISR ");
151 }
152
153 if ((channel->flags & DMA_CHANNEL_FLAG_LARGE_FIFO) != 0) {
154 len += sprintf(buf + len, "Fifo: 128 ");
155 } else {
156 len += sprintf(buf + len, "Fifo: 64 ");
157 }
158
159 if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
160 len +=
161 sprintf(buf + len, "InUse by %s",
162 DMA_gDeviceAttribute[channel->
163 devType].name);
164#if (DMA_DEBUG_TRACK_RESERVATION)
165 len +=
166 sprintf(buf + len, " (%s:%d)",
167 channel->fileName,
168 channel->lineNum);
169#endif
170 } else {
171 len += sprintf(buf + len, "Avail ");
172 }
173
174 if (channel->lastDevType != DMA_DEVICE_NONE) {
175 len +=
176 sprintf(buf + len, "Last use: %s ",
177 DMA_gDeviceAttribute[channel->
178 lastDevType].
179 name);
180 }
181
182 len += sprintf(buf + len, "\n");
183 }
184 }
185 up(&gDMA.lock);
186 *eof = 1;
187
188 return len;
189}
190
191/****************************************************************************/
192/**
193* Displays information for /proc/dma/devices
194*/
195/****************************************************************************/
196
197static int dma_proc_read_devices(char *buf, char **start, off_t offset,
198 int count, int *eof, void *data)
199{
200 int limit = count - 200;
201 int len = 0;
202 int devIdx;
203
204 if (down_interruptible(&gDMA.lock) < 0) {
205 return -ERESTARTSYS;
206 }
207
208 for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
209 DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
210
211 if (devAttr->name == NULL) {
212 continue;
213 }
214
215 if (len >= limit) {
216 break;
217 }
218
219 len += sprintf(buf + len, "%-12s ", devAttr->name);
220
221 if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
222 len +=
223 sprintf(buf + len, "Dedicated %d:%d ",
224 devAttr->dedicatedController,
225 devAttr->dedicatedChannel);
226 } else {
227 len += sprintf(buf + len, "Shared DMA:");
228 if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA0) != 0) {
229 len += sprintf(buf + len, "0");
230 }
231 if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA1) != 0) {
232 len += sprintf(buf + len, "1");
233 }
234 len += sprintf(buf + len, " ");
235 }
236 if ((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0) {
237 len += sprintf(buf + len, "NoISR ");
238 }
239 if ((devAttr->flags & DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO) != 0) {
240 len += sprintf(buf + len, "Allow-128 ");
241 }
242
243 len +=
244 sprintf(buf + len,
245 "Xfer #: %Lu Ticks: %Lu Bytes: %Lu DescLen: %u\n",
246 devAttr->numTransfers, devAttr->transferTicks,
247 devAttr->transferBytes,
248 devAttr->ring.bytesAllocated);
249
250 }
251
252 up(&gDMA.lock);
253 *eof = 1;
254
255 return len;
256}
257
258/****************************************************************************/
259/**
260* Determines if a DMA_Device_t is "valid".
261*
262* @return
263* TRUE - dma device is valid
264* FALSE - dma device isn't valid
265*/
266/****************************************************************************/
267
268static inline int IsDeviceValid(DMA_Device_t device)
269{
270 return (device >= 0) && (device < DMA_NUM_DEVICE_ENTRIES);
271}
272
273/****************************************************************************/
274/**
275* Translates a DMA handle into a pointer to a channel.
276*
277* @return
278* non-NULL - pointer to DMA_Channel_t
279* NULL - DMA Handle was invalid
280*/
281/****************************************************************************/
282
283static inline DMA_Channel_t *HandleToChannel(DMA_Handle_t handle)
284{
285 int controllerIdx;
286 int channelIdx;
287
288 controllerIdx = CONTROLLER_FROM_HANDLE(handle);
289 channelIdx = CHANNEL_FROM_HANDLE(handle);
290
291 if ((controllerIdx > DMA_NUM_CONTROLLERS)
292 || (channelIdx > DMA_NUM_CHANNELS)) {
293 return NULL;
294 }
295 return &gDMA.controller[controllerIdx].channel[channelIdx];
296}
297
298/****************************************************************************/
299/**
300* Interrupt handler which is called to process DMA interrupts.
301*/
302/****************************************************************************/
303
304static irqreturn_t dma_interrupt_handler(int irq, void *dev_id)
305{
306 DMA_Channel_t *channel;
307 DMA_DeviceAttribute_t *devAttr;
308 int irqStatus;
309
310 channel = (DMA_Channel_t *) dev_id;
311
312 /* Figure out why we were called, and knock down the interrupt */
313
314 irqStatus = dmacHw_getInterruptStatus(channel->dmacHwHandle);
315 dmacHw_clearInterrupt(channel->dmacHwHandle);
316
317 if ((channel->devType < 0)
318 || (channel->devType > DMA_NUM_DEVICE_ENTRIES)) {
319 printk(KERN_ERR "dma_interrupt_handler: Invalid devType: %d\n",
320 channel->devType);
321 return IRQ_NONE;
322 }
323 devAttr = &DMA_gDeviceAttribute[channel->devType];
324
325 /* Update stats */
326
327 if ((irqStatus & dmacHw_INTERRUPT_STATUS_TRANS) != 0) {
328 devAttr->transferTicks +=
329 (timer_get_tick_count() - devAttr->transferStartTime);
330 }
331
332 if ((irqStatus & dmacHw_INTERRUPT_STATUS_ERROR) != 0) {
333 printk(KERN_ERR
334 "dma_interrupt_handler: devType :%d DMA error (%s)\n",
335 channel->devType, devAttr->name);
336 } else {
337 devAttr->numTransfers++;
338 devAttr->transferBytes += devAttr->numBytes;
339 }
340
341 /* Call any installed handler */
342
343 if (devAttr->devHandler != NULL) {
344 devAttr->devHandler(channel->devType, irqStatus,
345 devAttr->userData);
346 }
347
348 return IRQ_HANDLED;
349}
350
351/****************************************************************************/
352/**
353* Allocates memory to hold a descriptor ring. The descriptor ring then
354* needs to be populated by making one or more calls to
355* dna_add_descriptors.
356*
357* The returned descriptor ring will be automatically initialized.
358*
359* @return
360* 0 Descriptor ring was allocated successfully
361* -EINVAL Invalid parameters passed in
362* -ENOMEM Unable to allocate memory for the desired number of descriptors.
363*/
364/****************************************************************************/
365
366int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */
367 int numDescriptors /* Number of descriptors that need to be allocated. */
368 ) {
369 size_t bytesToAlloc = dmacHw_descriptorLen(numDescriptors);
370
371 if ((ring == NULL) || (numDescriptors <= 0)) {
372 return -EINVAL;
373 }
374
375 ring->physAddr = 0;
376 ring->descriptorsAllocated = 0;
377 ring->bytesAllocated = 0;
378
379 ring->virtAddr = dma_alloc_writecombine(NULL,
380 bytesToAlloc,
381 &ring->physAddr,
382 GFP_KERNEL);
383 if (ring->virtAddr == NULL) {
384 return -ENOMEM;
385 }
386
387 ring->bytesAllocated = bytesToAlloc;
388 ring->descriptorsAllocated = numDescriptors;
389
390 return dma_init_descriptor_ring(ring, numDescriptors);
391}
392
393EXPORT_SYMBOL(dma_alloc_descriptor_ring);
394
395/****************************************************************************/
396/**
397* Releases the memory which was previously allocated for a descriptor ring.
398*/
399/****************************************************************************/
400
401void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */
402 ) {
403 if (ring->virtAddr != NULL) {
404 dma_free_writecombine(NULL,
405 ring->bytesAllocated,
406 ring->virtAddr, ring->physAddr);
407 }
408
409 ring->bytesAllocated = 0;
410 ring->descriptorsAllocated = 0;
411 ring->virtAddr = NULL;
412 ring->physAddr = 0;
413}
414
415EXPORT_SYMBOL(dma_free_descriptor_ring);
416
417/****************************************************************************/
418/**
419* Initializes a descriptor ring, so that descriptors can be added to it.
420* Once a descriptor ring has been allocated, it may be reinitialized for
421* use with additional/different regions of memory.
422*
423* Note that if 7 descriptors are allocated, it's perfectly acceptable to
424* initialize the ring with a smaller number of descriptors. The amount
425* of memory allocated for the descriptor ring will not be reduced, and
426* the descriptor ring may be reinitialized later
427*
428* @return
429* 0 Descriptor ring was initialized successfully
430* -ENOMEM The descriptor which was passed in has insufficient space
431* to hold the desired number of descriptors.
432*/
433/****************************************************************************/
434
435int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */
436 int numDescriptors /* Number of descriptors to initialize. */
437 ) {
438 if (ring->virtAddr == NULL) {
439 return -EINVAL;
440 }
441 if (dmacHw_initDescriptor(ring->virtAddr,
442 ring->physAddr,
443 ring->bytesAllocated, numDescriptors) < 0) {
444 printk(KERN_ERR
445 "dma_init_descriptor_ring: dmacHw_initDescriptor failed\n");
446 return -ENOMEM;
447 }
448
449 return 0;
450}
451
452EXPORT_SYMBOL(dma_init_descriptor_ring);
453
454/****************************************************************************/
455/**
456* Determines the number of descriptors which would be required for a
457* transfer of the indicated memory region.
458*
459* This function also needs to know which DMA device this transfer will
460* be destined for, so that the appropriate DMA configuration can be retrieved.
461* DMA parameters such as transfer width, and whether this is a memory-to-memory
462* or memory-to-peripheral, etc can all affect the actual number of descriptors
463* required.
464*
465* @return
466* > 0 Returns the number of descriptors required for the indicated transfer
467* -ENODEV - Device handed in is invalid.
468* -EINVAL Invalid parameters
469* -ENOMEM Memory exhausted
470*/
471/****************************************************************************/
472
473int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */
474 dma_addr_t srcData, /* Place to get data to write to device */
475 dma_addr_t dstData, /* Pointer to device data address */
476 size_t numBytes /* Number of bytes to transfer to the device */
477 ) {
478 int numDescriptors;
479 DMA_DeviceAttribute_t *devAttr;
480
481 if (!IsDeviceValid(device)) {
482 return -ENODEV;
483 }
484 devAttr = &DMA_gDeviceAttribute[device];
485
486 numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
487 (void *)srcData,
488 (void *)dstData,
489 numBytes);
490 if (numDescriptors < 0) {
491 printk(KERN_ERR
492 "dma_calculate_descriptor_count: dmacHw_calculateDescriptorCount failed\n");
493 return -EINVAL;
494 }
495
496 return numDescriptors;
497}
498
499EXPORT_SYMBOL(dma_calculate_descriptor_count);
500
501/****************************************************************************/
502/**
503* Adds a region of memory to the descriptor ring. Note that it may take
504* multiple descriptors for each region of memory. It is the callers
505* responsibility to allocate a sufficiently large descriptor ring.
506*
507* @return
508* 0 Descriptors were added successfully
509* -ENODEV Device handed in is invalid.
510* -EINVAL Invalid parameters
511* -ENOMEM Memory exhausted
512*/
513/****************************************************************************/
514
515int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */
516 DMA_Device_t device, /* DMA Device that descriptors are for */
517 dma_addr_t srcData, /* Place to get data (memory or device) */
518 dma_addr_t dstData, /* Place to put data (memory or device) */
519 size_t numBytes /* Number of bytes to transfer to the device */
520 ) {
521 int rc;
522 DMA_DeviceAttribute_t *devAttr;
523
524 if (!IsDeviceValid(device)) {
525 return -ENODEV;
526 }
527 devAttr = &DMA_gDeviceAttribute[device];
528
529 rc = dmacHw_setDataDescriptor(&devAttr->config,
530 ring->virtAddr,
531 (void *)srcData,
532 (void *)dstData, numBytes);
533 if (rc < 0) {
534 printk(KERN_ERR
535 "dma_add_descriptors: dmacHw_setDataDescriptor failed with code: %d\n",
536 rc);
537 return -ENOMEM;
538 }
539
540 return 0;
541}
542
543EXPORT_SYMBOL(dma_add_descriptors);
544
545/****************************************************************************/
546/**
547* Sets the descriptor ring associated with a device.
548*
549* Once set, the descriptor ring will be associated with the device, even
550* across channel request/free calls. Passing in a NULL descriptor ring
551* will release any descriptor ring currently associated with the device.
552*
553* Note: If you call dma_transfer, or one of the other dma_alloc_ functions
554* the descriptor ring may be released and reallocated.
555*
556* Note: This function will release the descriptor memory for any current
557* descriptor ring associated with this device.
558*
559* @return
560* 0 Descriptors were added successfully
561* -ENODEV Device handed in is invalid.
562*/
563/****************************************************************************/
564
565int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */
566 DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */
567 ) {
568 DMA_DeviceAttribute_t *devAttr;
569
570 if (!IsDeviceValid(device)) {
571 return -ENODEV;
572 }
573 devAttr = &DMA_gDeviceAttribute[device];
574
575 /* Free the previously allocated descriptor ring */
576
577 dma_free_descriptor_ring(&devAttr->ring);
578
579 if (ring != NULL) {
580 /* Copy in the new one */
581
582 devAttr->ring = *ring;
583 }
584
585 /* Set things up so that if dma_transfer is called then this descriptor */
586 /* ring will get freed. */
587
588 devAttr->prevSrcData = 0;
589 devAttr->prevDstData = 0;
590 devAttr->prevNumBytes = 0;
591
592 return 0;
593}
594
595EXPORT_SYMBOL(dma_set_device_descriptor_ring);
596
597/****************************************************************************/
598/**
599* Retrieves the descriptor ring associated with a device.
600*
601* @return
602* 0 Descriptors were added successfully
603* -ENODEV Device handed in is invalid.
604*/
605/****************************************************************************/
606
607int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */
608 DMA_DescriptorRing_t *ring /* Place to store retrieved ring */
609 ) {
610 DMA_DeviceAttribute_t *devAttr;
611
612 memset(ring, 0, sizeof(*ring));
613
614 if (!IsDeviceValid(device)) {
615 return -ENODEV;
616 }
617 devAttr = &DMA_gDeviceAttribute[device];
618
619 *ring = devAttr->ring;
620
621 return 0;
622}
623
624EXPORT_SYMBOL(dma_get_device_descriptor_ring);
625
626/****************************************************************************/
627/**
628* Configures a DMA channel.
629*
630* @return
631* >= 0 - Initialization was successfull.
632*
633* -EBUSY - Device is currently being used.
634* -ENODEV - Device handed in is invalid.
635*/
636/****************************************************************************/
637
638static int ConfigChannel(DMA_Handle_t handle)
639{
640 DMA_Channel_t *channel;
641 DMA_DeviceAttribute_t *devAttr;
642 int controllerIdx;
643
644 channel = HandleToChannel(handle);
645 if (channel == NULL) {
646 return -ENODEV;
647 }
648 devAttr = &DMA_gDeviceAttribute[channel->devType];
649 controllerIdx = CONTROLLER_FROM_HANDLE(handle);
650
651 if ((devAttr->flags & DMA_DEVICE_FLAG_PORT_PER_DMAC) != 0) {
652 if (devAttr->config.transferType ==
653 dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL) {
654 devAttr->config.dstPeripheralPort =
655 devAttr->dmacPort[controllerIdx];
656 } else if (devAttr->config.transferType ==
657 dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) {
658 devAttr->config.srcPeripheralPort =
659 devAttr->dmacPort[controllerIdx];
660 }
661 }
662
663 if (dmacHw_configChannel(channel->dmacHwHandle, &devAttr->config) != 0) {
664 printk(KERN_ERR "ConfigChannel: dmacHw_configChannel failed\n");
665 return -EIO;
666 }
667
668 return 0;
669}
670
671/****************************************************************************/
672/**
673* Intializes all of the data structures associated with the DMA.
674* @return
675* >= 0 - Initialization was successfull.
676*
677* -EBUSY - Device is currently being used.
678* -ENODEV - Device handed in is invalid.
679*/
680/****************************************************************************/
681
682int dma_init(void)
683{
684 int rc = 0;
685 int controllerIdx;
686 int channelIdx;
687 DMA_Device_t devIdx;
688 DMA_Channel_t *channel;
689 DMA_Handle_t dedicatedHandle;
690
691 memset(&gDMA, 0, sizeof(gDMA));
692
693 init_MUTEX_LOCKED(&gDMA.lock);
694 init_waitqueue_head(&gDMA.freeChannelQ);
695
696 /* Initialize the Hardware */
697
698 dmacHw_initDma();
699
700 /* Start off by marking all of the DMA channels as shared. */
701
702 for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
703 controllerIdx++) {
704 for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
705 channelIdx++) {
706 channel =
707 &gDMA.controller[controllerIdx].channel[channelIdx];
708
709 channel->flags = 0;
710 channel->devType = DMA_DEVICE_NONE;
711 channel->lastDevType = DMA_DEVICE_NONE;
712
713#if (DMA_DEBUG_TRACK_RESERVATION)
714 channel->fileName = "";
715 channel->lineNum = 0;
716#endif
717
718 channel->dmacHwHandle =
719 dmacHw_getChannelHandle(dmacHw_MAKE_CHANNEL_ID
720 (controllerIdx,
721 channelIdx));
722 dmacHw_initChannel(channel->dmacHwHandle);
723 }
724 }
725
726 /* Record any special attributes that channels may have */
727
728 gDMA.controller[0].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
729 gDMA.controller[0].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
730 gDMA.controller[1].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
731 gDMA.controller[1].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
732
733 /* Now walk through and record the dedicated channels. */
734
735 for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
736 DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
737
738 if (((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0)
739 && ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0)) {
740 printk(KERN_ERR
741 "DMA Device: %s Can only request NO_ISR for dedicated devices\n",
742 devAttr->name);
743 rc = -EINVAL;
744 goto out;
745 }
746
747 if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
748 /* This is a dedicated device. Mark the channel as being reserved. */
749
750 if (devAttr->dedicatedController >= DMA_NUM_CONTROLLERS) {
751 printk(KERN_ERR
752 "DMA Device: %s DMA Controller %d is out of range\n",
753 devAttr->name,
754 devAttr->dedicatedController);
755 rc = -EINVAL;
756 goto out;
757 }
758
759 if (devAttr->dedicatedChannel >= DMA_NUM_CHANNELS) {
760 printk(KERN_ERR
761 "DMA Device: %s DMA Channel %d is out of range\n",
762 devAttr->name,
763 devAttr->dedicatedChannel);
764 rc = -EINVAL;
765 goto out;
766 }
767
768 dedicatedHandle =
769 MAKE_HANDLE(devAttr->dedicatedController,
770 devAttr->dedicatedChannel);
771 channel = HandleToChannel(dedicatedHandle);
772
773 if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
774 0) {
775 printk
776 ("DMA Device: %s attempting to use same DMA Controller:Channel (%d:%d) as %s\n",
777 devAttr->name,
778 devAttr->dedicatedController,
779 devAttr->dedicatedChannel,
780 DMA_gDeviceAttribute[channel->devType].
781 name);
782 rc = -EBUSY;
783 goto out;
784 }
785
786 channel->flags |= DMA_CHANNEL_FLAG_IS_DEDICATED;
787 channel->devType = devIdx;
788
789 if (devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) {
790 channel->flags |= DMA_CHANNEL_FLAG_NO_ISR;
791 }
792
793 /* For dedicated channels, we can go ahead and configure the DMA channel now */
794 /* as well. */
795
796 ConfigChannel(dedicatedHandle);
797 }
798 }
799
800 /* Go through and register the interrupt handlers */
801
802 for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
803 controllerIdx++) {
804 for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
805 channelIdx++) {
806 channel =
807 &gDMA.controller[controllerIdx].channel[channelIdx];
808
809 if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) == 0) {
810 snprintf(channel->name, sizeof(channel->name),
811 "dma %d:%d %s", controllerIdx,
812 channelIdx,
813 channel->devType ==
814 DMA_DEVICE_NONE ? "" :
815 DMA_gDeviceAttribute[channel->devType].
816 name);
817
818 rc =
819 request_irq(IRQ_DMA0C0 +
820 (controllerIdx *
821 DMA_NUM_CHANNELS) +
822 channelIdx,
823 dma_interrupt_handler,
824 IRQF_DISABLED, channel->name,
825 channel);
826 if (rc != 0) {
827 printk(KERN_ERR
828 "request_irq for IRQ_DMA%dC%d failed\n",
829 controllerIdx, channelIdx);
830 }
831 }
832 }
833 }
834
835 /* Create /proc/dma/channels and /proc/dma/devices */
836
837 gDmaDir = create_proc_entry("dma", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
838
839 if (gDmaDir == NULL) {
840 printk(KERN_ERR "Unable to create /proc/dma\n");
841 } else {
842 create_proc_read_entry("channels", 0, gDmaDir,
843 dma_proc_read_channels, NULL);
844 create_proc_read_entry("devices", 0, gDmaDir,
845 dma_proc_read_devices, NULL);
846 create_proc_read_entry("mem-type", 0, gDmaDir,
847 dma_proc_read_mem_type, NULL);
848 }
849
850out:
851
852 up(&gDMA.lock);
853
854 return rc;
855}
856
857/****************************************************************************/
858/**
859* Reserves a channel for use with @a dev. If the device is setup to use
860* a shared channel, then this function will block until a free channel
861* becomes available.
862*
863* @return
864* >= 0 - A valid DMA Handle.
865* -EBUSY - Device is currently being used.
866* -ENODEV - Device handed in is invalid.
867*/
868/****************************************************************************/
869
870#if (DMA_DEBUG_TRACK_RESERVATION)
871DMA_Handle_t dma_request_channel_dbg
872 (DMA_Device_t dev, const char *fileName, int lineNum)
873#else
874DMA_Handle_t dma_request_channel(DMA_Device_t dev)
875#endif
876{
877 DMA_Handle_t handle;
878 DMA_DeviceAttribute_t *devAttr;
879 DMA_Channel_t *channel;
880 int controllerIdx;
881 int controllerIdx2;
882 int channelIdx;
883
884 if (down_interruptible(&gDMA.lock) < 0) {
885 return -ERESTARTSYS;
886 }
887
888 if ((dev < 0) || (dev >= DMA_NUM_DEVICE_ENTRIES)) {
889 handle = -ENODEV;
890 goto out;
891 }
892 devAttr = &DMA_gDeviceAttribute[dev];
893
894#if (DMA_DEBUG_TRACK_RESERVATION)
895 {
896 char *s;
897
898 s = strrchr(fileName, '/');
899 if (s != NULL) {
900 fileName = s + 1;
901 }
902 }
903#endif
904 if ((devAttr->flags & DMA_DEVICE_FLAG_IN_USE) != 0) {
905 /* This device has already been requested and not been freed */
906
907 printk(KERN_ERR "%s: device %s is already requested\n",
908 __func__, devAttr->name);
909 handle = -EBUSY;
910 goto out;
911 }
912
913 if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
914 /* This device has a dedicated channel. */
915
916 channel =
917 &gDMA.controller[devAttr->dedicatedController].
918 channel[devAttr->dedicatedChannel];
919 if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
920 handle = -EBUSY;
921 goto out;
922 }
923
924 channel->flags |= DMA_CHANNEL_FLAG_IN_USE;
925 devAttr->flags |= DMA_DEVICE_FLAG_IN_USE;
926
927#if (DMA_DEBUG_TRACK_RESERVATION)
928 channel->fileName = fileName;
929 channel->lineNum = lineNum;
930#endif
931 handle =
932 MAKE_HANDLE(devAttr->dedicatedController,
933 devAttr->dedicatedChannel);
934 goto out;
935 }
936
937 /* This device needs to use one of the shared channels. */
938
939 handle = DMA_INVALID_HANDLE;
940 while (handle == DMA_INVALID_HANDLE) {
941 /* Scan through the shared channels and see if one is available */
942
943 for (controllerIdx2 = 0; controllerIdx2 < DMA_NUM_CONTROLLERS;
944 controllerIdx2++) {
945 /* Check to see if we should try on controller 1 first. */
946
947 controllerIdx = controllerIdx2;
948 if ((devAttr->
949 flags & DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST) != 0) {
950 controllerIdx = 1 - controllerIdx;
951 }
952
953 /* See if the device is available on the controller being tested */
954
955 if ((devAttr->
956 flags & (DMA_DEVICE_FLAG_ON_DMA0 << controllerIdx))
957 != 0) {
958 for (channelIdx = 0;
959 channelIdx < DMA_NUM_CHANNELS;
960 channelIdx++) {
961 channel =
962 &gDMA.controller[controllerIdx].
963 channel[channelIdx];
964
965 if (((channel->
966 flags &
967 DMA_CHANNEL_FLAG_IS_DEDICATED) ==
968 0)
969 &&
970 ((channel->
971 flags & DMA_CHANNEL_FLAG_IN_USE)
972 == 0)) {
973 if (((channel->
974 flags &
975 DMA_CHANNEL_FLAG_LARGE_FIFO)
976 != 0)
977 &&
978 ((devAttr->
979 flags &
980 DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO)
981 == 0)) {
982 /* This channel is a large fifo - don't tie it up */
983 /* with devices that we don't want using it. */
984
985 continue;
986 }
987
988 channel->flags |=
989 DMA_CHANNEL_FLAG_IN_USE;
990 channel->devType = dev;
991 devAttr->flags |=
992 DMA_DEVICE_FLAG_IN_USE;
993
994#if (DMA_DEBUG_TRACK_RESERVATION)
995 channel->fileName = fileName;
996 channel->lineNum = lineNum;
997#endif
998 handle =
999 MAKE_HANDLE(controllerIdx,
1000 channelIdx);
1001
1002 /* Now that we've reserved the channel - we can go ahead and configure it */
1003
1004 if (ConfigChannel(handle) != 0) {
1005 handle = -EIO;
1006 printk(KERN_ERR
1007 "dma_request_channel: ConfigChannel failed\n");
1008 }
1009 goto out;
1010 }
1011 }
1012 }
1013 }
1014
1015 /* No channels are currently available. Let's wait for one to free up. */
1016
1017 {
1018 DEFINE_WAIT(wait);
1019
1020 prepare_to_wait(&gDMA.freeChannelQ, &wait,
1021 TASK_INTERRUPTIBLE);
1022 up(&gDMA.lock);
1023 schedule();
1024 finish_wait(&gDMA.freeChannelQ, &wait);
1025
1026 if (signal_pending(current)) {
1027 /* We don't currently hold gDMA.lock, so we return directly */
1028
1029 return -ERESTARTSYS;
1030 }
1031 }
1032
1033 if (down_interruptible(&gDMA.lock)) {
1034 return -ERESTARTSYS;
1035 }
1036 }
1037
1038out:
1039 up(&gDMA.lock);
1040
1041 return handle;
1042}
1043
1044/* Create both _dbg and non _dbg functions for modules. */
1045
1046#if (DMA_DEBUG_TRACK_RESERVATION)
1047#undef dma_request_channel
1048DMA_Handle_t dma_request_channel(DMA_Device_t dev)
1049{
1050 return dma_request_channel_dbg(dev, __FILE__, __LINE__);
1051}
1052
1053EXPORT_SYMBOL(dma_request_channel_dbg);
1054#endif
1055EXPORT_SYMBOL(dma_request_channel);
1056
1057/****************************************************************************/
1058/**
1059* Frees a previously allocated DMA Handle.
1060*/
1061/****************************************************************************/
1062
1063int dma_free_channel(DMA_Handle_t handle /* DMA handle. */
1064 ) {
1065 int rc = 0;
1066 DMA_Channel_t *channel;
1067 DMA_DeviceAttribute_t *devAttr;
1068
1069 if (down_interruptible(&gDMA.lock) < 0) {
1070 return -ERESTARTSYS;
1071 }
1072
1073 channel = HandleToChannel(handle);
1074 if (channel == NULL) {
1075 rc = -EINVAL;
1076 goto out;
1077 }
1078
1079 devAttr = &DMA_gDeviceAttribute[channel->devType];
1080
1081 if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) == 0) {
1082 channel->lastDevType = channel->devType;
1083 channel->devType = DMA_DEVICE_NONE;
1084 }
1085 channel->flags &= ~DMA_CHANNEL_FLAG_IN_USE;
1086 devAttr->flags &= ~DMA_DEVICE_FLAG_IN_USE;
1087
1088out:
1089 up(&gDMA.lock);
1090
1091 wake_up_interruptible(&gDMA.freeChannelQ);
1092
1093 return rc;
1094}
1095
1096EXPORT_SYMBOL(dma_free_channel);
1097
1098/****************************************************************************/
1099/**
1100* Determines if a given device has been configured as using a shared
1101* channel.
1102*
1103* @return
1104* 0 Device uses a dedicated channel
1105* > zero Device uses a shared channel
1106* < zero Error code
1107*/
1108/****************************************************************************/
1109
1110int dma_device_is_channel_shared(DMA_Device_t device /* Device to check. */
1111 ) {
1112 DMA_DeviceAttribute_t *devAttr;
1113
1114 if (!IsDeviceValid(device)) {
1115 return -ENODEV;
1116 }
1117 devAttr = &DMA_gDeviceAttribute[device];
1118
1119 return ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0);
1120}
1121
1122EXPORT_SYMBOL(dma_device_is_channel_shared);
1123
1124/****************************************************************************/
1125/**
1126* Allocates buffers for the descriptors. This is normally done automatically
1127* but needs to be done explicitly when initiating a dma from interrupt
1128* context.
1129*
1130* @return
1131* 0 Descriptors were allocated successfully
1132* -EINVAL Invalid device type for this kind of transfer
1133* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
1134* -ENOMEM Memory exhausted
1135*/
1136/****************************************************************************/
1137
1138int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */
1139 dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
1140 dma_addr_t srcData, /* Place to get data to write to device */
1141 dma_addr_t dstData, /* Pointer to device data address */
1142 size_t numBytes /* Number of bytes to transfer to the device */
1143 ) {
1144 DMA_Channel_t *channel;
1145 DMA_DeviceAttribute_t *devAttr;
1146 int numDescriptors;
1147 size_t ringBytesRequired;
1148 int rc = 0;
1149
1150 channel = HandleToChannel(handle);
1151 if (channel == NULL) {
1152 return -ENODEV;
1153 }
1154
1155 devAttr = &DMA_gDeviceAttribute[channel->devType];
1156
1157 if (devAttr->config.transferType != transferType) {
1158 return -EINVAL;
1159 }
1160
1161 /* Figure out how many descriptors we need. */
1162
1163 /* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
1164 /* srcData, dstData, numBytes); */
1165
1166 numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
1167 (void *)srcData,
1168 (void *)dstData,
1169 numBytes);
1170 if (numDescriptors < 0) {
1171 printk(KERN_ERR "%s: dmacHw_calculateDescriptorCount failed\n",
1172 __func__);
1173 return -EINVAL;
1174 }
1175
1176 /* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
1177 /* a new one. */
1178
1179 ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
1180
1181 /* printk("ringBytesRequired: %d\n", ringBytesRequired); */
1182
1183 if (ringBytesRequired > devAttr->ring.bytesAllocated) {
1184 /* Make sure that this code path is never taken from interrupt context. */
1185 /* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
1186 /* allocation needs to have already been done. */
1187
1188 might_sleep();
1189
1190 /* Free the old descriptor ring and allocate a new one. */
1191
1192 dma_free_descriptor_ring(&devAttr->ring);
1193
1194 /* And allocate a new one. */
1195
1196 rc =
1197 dma_alloc_descriptor_ring(&devAttr->ring,
1198 numDescriptors);
1199 if (rc < 0) {
1200 printk(KERN_ERR
1201 "%s: dma_alloc_descriptor_ring(%d) failed\n",
1202 __func__, numDescriptors);
1203 return rc;
1204 }
1205 /* Setup the descriptor for this transfer */
1206
1207 if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
1208 devAttr->ring.physAddr,
1209 devAttr->ring.bytesAllocated,
1210 numDescriptors) < 0) {
1211 printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n",
1212 __func__);
1213 return -EINVAL;
1214 }
1215 } else {
1216 /* We've already got enough ring buffer allocated. All we need to do is reset */
1217 /* any control information, just in case the previous DMA was stopped. */
1218
1219 dmacHw_resetDescriptorControl(devAttr->ring.virtAddr);
1220 }
1221
1222 /* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
1223 /* as last time, then we don't need to call setDataDescriptor again. */
1224
1225 if (dmacHw_setDataDescriptor(&devAttr->config,
1226 devAttr->ring.virtAddr,
1227 (void *)srcData,
1228 (void *)dstData, numBytes) < 0) {
1229 printk(KERN_ERR "%s: dmacHw_setDataDescriptor failed\n",
1230 __func__);
1231 return -EINVAL;
1232 }
1233
1234 /* Remember the critical information for this transfer so that we can eliminate */
1235 /* another call to dma_alloc_descriptors if the caller reuses the same buffers */
1236
1237 devAttr->prevSrcData = srcData;
1238 devAttr->prevDstData = dstData;
1239 devAttr->prevNumBytes = numBytes;
1240
1241 return 0;
1242}
1243
1244EXPORT_SYMBOL(dma_alloc_descriptors);
1245
1246/****************************************************************************/
1247/**
1248* Allocates and sets up descriptors for a double buffered circular buffer.
1249*
1250* This is primarily intended to be used for things like the ingress samples
1251* from a microphone.
1252*
1253* @return
1254* > 0 Number of descriptors actually allocated.
1255* -EINVAL Invalid device type for this kind of transfer
1256* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
1257* -ENOMEM Memory exhausted
1258*/
1259/****************************************************************************/
1260
1261int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
1262 dma_addr_t srcData, /* Physical address of source data */
1263 dma_addr_t dstData1, /* Physical address of first destination buffer */
1264 dma_addr_t dstData2, /* Physical address of second destination buffer */
1265 size_t numBytes /* Number of bytes in each destination buffer */
1266 ) {
1267 DMA_Channel_t *channel;
1268 DMA_DeviceAttribute_t *devAttr;
1269 int numDst1Descriptors;
1270 int numDst2Descriptors;
1271 int numDescriptors;
1272 size_t ringBytesRequired;
1273 int rc = 0;
1274
1275 channel = HandleToChannel(handle);
1276 if (channel == NULL) {
1277 return -ENODEV;
1278 }
1279
1280 devAttr = &DMA_gDeviceAttribute[channel->devType];
1281
1282 /* Figure out how many descriptors we need. */
1283
1284 /* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
1285 /* srcData, dstData, numBytes); */
1286
1287 numDst1Descriptors =
1288 dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
1289 (void *)dstData1, numBytes);
1290 if (numDst1Descriptors < 0) {
1291 return -EINVAL;
1292 }
1293 numDst2Descriptors =
1294 dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
1295 (void *)dstData2, numBytes);
1296 if (numDst2Descriptors < 0) {
1297 return -EINVAL;
1298 }
1299 numDescriptors = numDst1Descriptors + numDst2Descriptors;
1300 /* printk("numDescriptors: %d\n", numDescriptors); */
1301
1302 /* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
1303 /* a new one. */
1304
1305 ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
1306
1307 /* printk("ringBytesRequired: %d\n", ringBytesRequired); */
1308
1309 if (ringBytesRequired > devAttr->ring.bytesAllocated) {
1310 /* Make sure that this code path is never taken from interrupt context. */
1311 /* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
1312 /* allocation needs to have already been done. */
1313
1314 might_sleep();
1315
1316 /* Free the old descriptor ring and allocate a new one. */
1317
1318 dma_free_descriptor_ring(&devAttr->ring);
1319
1320 /* And allocate a new one. */
1321
1322 rc =
1323 dma_alloc_descriptor_ring(&devAttr->ring,
1324 numDescriptors);
1325 if (rc < 0) {
1326 printk(KERN_ERR
1327 "%s: dma_alloc_descriptor_ring(%d) failed\n",
1328 __func__, ringBytesRequired);
1329 return rc;
1330 }
1331 }
1332
1333 /* Setup the descriptor for this transfer. Since this function is used with */
1334 /* CONTINUOUS DMA operations, we need to reinitialize every time, otherwise */
1335 /* setDataDescriptor will keep trying to append onto the end. */
1336
1337 if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
1338 devAttr->ring.physAddr,
1339 devAttr->ring.bytesAllocated,
1340 numDescriptors) < 0) {
1341 printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n", __func__);
1342 return -EINVAL;
1343 }
1344
1345 /* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
1346 /* as last time, then we don't need to call setDataDescriptor again. */
1347
1348 if (dmacHw_setDataDescriptor(&devAttr->config,
1349 devAttr->ring.virtAddr,
1350 (void *)srcData,
1351 (void *)dstData1, numBytes) < 0) {
1352 printk(KERN_ERR "%s: dmacHw_setDataDescriptor 1 failed\n",
1353 __func__);
1354 return -EINVAL;
1355 }
1356 if (dmacHw_setDataDescriptor(&devAttr->config,
1357 devAttr->ring.virtAddr,
1358 (void *)srcData,
1359 (void *)dstData2, numBytes) < 0) {
1360 printk(KERN_ERR "%s: dmacHw_setDataDescriptor 2 failed\n",
1361 __func__);
1362 return -EINVAL;
1363 }
1364
1365 /* You should use dma_start_transfer rather than dma_transfer_xxx so we don't */
1366 /* try to make the 'prev' variables right. */
1367
1368 devAttr->prevSrcData = 0;
1369 devAttr->prevDstData = 0;
1370 devAttr->prevNumBytes = 0;
1371
1372 return numDescriptors;
1373}
1374
1375EXPORT_SYMBOL(dma_alloc_double_dst_descriptors);
1376
1377/****************************************************************************/
1378/**
1379* Initiates a transfer when the descriptors have already been setup.
1380*
1381* This is a special case, and normally, the dma_transfer_xxx functions should
1382* be used.
1383*
1384* @return
1385* 0 Transfer was started successfully
1386* -ENODEV Invalid handle
1387*/
1388/****************************************************************************/
1389
1390int dma_start_transfer(DMA_Handle_t handle)
1391{
1392 DMA_Channel_t *channel;
1393 DMA_DeviceAttribute_t *devAttr;
1394
1395 channel = HandleToChannel(handle);
1396 if (channel == NULL) {
1397 return -ENODEV;
1398 }
1399 devAttr = &DMA_gDeviceAttribute[channel->devType];
1400
1401 dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
1402 devAttr->ring.virtAddr);
1403
1404 /* Since we got this far, everything went successfully */
1405
1406 return 0;
1407}
1408
1409EXPORT_SYMBOL(dma_start_transfer);
1410
1411/****************************************************************************/
1412/**
1413* Stops a previously started DMA transfer.
1414*
1415* @return
1416* 0 Transfer was stopped successfully
1417* -ENODEV Invalid handle
1418*/
1419/****************************************************************************/
1420
1421int dma_stop_transfer(DMA_Handle_t handle)
1422{
1423 DMA_Channel_t *channel;
1424
1425 channel = HandleToChannel(handle);
1426 if (channel == NULL) {
1427 return -ENODEV;
1428 }
1429
1430 dmacHw_stopTransfer(channel->dmacHwHandle);
1431
1432 return 0;
1433}
1434
1435EXPORT_SYMBOL(dma_stop_transfer);
1436
1437/****************************************************************************/
1438/**
1439* Waits for a DMA to complete by polling. This function is only intended
1440* to be used for testing. Interrupts should be used for most DMA operations.
1441*/
1442/****************************************************************************/
1443
1444int dma_wait_transfer_done(DMA_Handle_t handle)
1445{
1446 DMA_Channel_t *channel;
1447 dmacHw_TRANSFER_STATUS_e status;
1448
1449 channel = HandleToChannel(handle);
1450 if (channel == NULL) {
1451 return -ENODEV;
1452 }
1453
1454 while ((status =
1455 dmacHw_transferCompleted(channel->dmacHwHandle)) ==
1456 dmacHw_TRANSFER_STATUS_BUSY) {
1457 ;
1458 }
1459
1460 if (status == dmacHw_TRANSFER_STATUS_ERROR) {
1461 printk(KERN_ERR "%s: DMA transfer failed\n", __func__);
1462 return -EIO;
1463 }
1464 return 0;
1465}
1466
1467EXPORT_SYMBOL(dma_wait_transfer_done);
1468
1469/****************************************************************************/
1470/**
1471* Initiates a DMA, allocating the descriptors as required.
1472*
1473* @return
1474* 0 Transfer was started successfully
1475* -EINVAL Invalid device type for this kind of transfer
1476* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
1477*/
1478/****************************************************************************/
1479
1480int dma_transfer(DMA_Handle_t handle, /* DMA Handle */
1481 dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
1482 dma_addr_t srcData, /* Place to get data to write to device */
1483 dma_addr_t dstData, /* Pointer to device data address */
1484 size_t numBytes /* Number of bytes to transfer to the device */
1485 ) {
1486 DMA_Channel_t *channel;
1487 DMA_DeviceAttribute_t *devAttr;
1488 int rc = 0;
1489
1490 channel = HandleToChannel(handle);
1491 if (channel == NULL) {
1492 return -ENODEV;
1493 }
1494
1495 devAttr = &DMA_gDeviceAttribute[channel->devType];
1496
1497 if (devAttr->config.transferType != transferType) {
1498 return -EINVAL;
1499 }
1500
1501 /* We keep track of the information about the previous request for this */
1502 /* device, and if the attributes match, then we can use the descriptors we setup */
1503 /* the last time, and not have to reinitialize everything. */
1504
1505 {
1506 rc =
1507 dma_alloc_descriptors(handle, transferType, srcData,
1508 dstData, numBytes);
1509 if (rc != 0) {
1510 return rc;
1511 }
1512 }
1513
1514 /* And kick off the transfer */
1515
1516 devAttr->numBytes = numBytes;
1517 devAttr->transferStartTime = timer_get_tick_count();
1518
1519 dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
1520 devAttr->ring.virtAddr);
1521
1522 /* Since we got this far, everything went successfully */
1523
1524 return 0;
1525}
1526
1527EXPORT_SYMBOL(dma_transfer);
1528
1529/****************************************************************************/
1530/**
1531* Set the callback function which will be called when a transfer completes.
1532* If a NULL callback function is set, then no callback will occur.
1533*
1534* @note @a devHandler will be called from IRQ context.
1535*
1536* @return
1537* 0 - Success
1538* -ENODEV - Device handed in is invalid.
1539*/
1540/****************************************************************************/
1541
1542int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */
1543 DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */
1544 void *userData /* Pointer which will be passed to devHandler. */
1545 ) {
1546 DMA_DeviceAttribute_t *devAttr;
1547 unsigned long flags;
1548
1549 if (!IsDeviceValid(dev)) {
1550 return -ENODEV;
1551 }
1552 devAttr = &DMA_gDeviceAttribute[dev];
1553
1554 local_irq_save(flags);
1555
1556 devAttr->userData = userData;
1557 devAttr->devHandler = devHandler;
1558
1559 local_irq_restore(flags);
1560
1561 return 0;
1562}
1563
1564EXPORT_SYMBOL(dma_set_device_handler);
1565
1566/****************************************************************************/
1567/**
1568* Initializes a memory mapping structure
1569*/
1570/****************************************************************************/
1571
1572int dma_init_mem_map(DMA_MemMap_t *memMap)
1573{
1574 memset(memMap, 0, sizeof(*memMap));
1575
1576 init_MUTEX(&memMap->lock);
1577
1578 return 0;
1579}
1580
1581EXPORT_SYMBOL(dma_init_mem_map);
1582
1583/****************************************************************************/
1584/**
1585* Releases any memory currently being held by a memory mapping structure.
1586*/
1587/****************************************************************************/
1588
1589int dma_term_mem_map(DMA_MemMap_t *memMap)
1590{
1591 down(&memMap->lock); /* Just being paranoid */
1592
1593 /* Free up any allocated memory */
1594
1595 up(&memMap->lock);
1596 memset(memMap, 0, sizeof(*memMap));
1597
1598 return 0;
1599}
1600
1601EXPORT_SYMBOL(dma_term_mem_map);
1602
1603/****************************************************************************/
1604/**
1605* Looks at a memory address and categorizes it.
1606*
1607* @return One of the values from the DMA_MemType_t enumeration.
1608*/
1609/****************************************************************************/
1610
1611DMA_MemType_t dma_mem_type(void *addr)
1612{
1613 unsigned long addrVal = (unsigned long)addr;
1614
1615 if (addrVal >= VMALLOC_END) {
1616 /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
1617
1618 /* dma_alloc_xxx pages are physically and virtually contiguous */
1619
1620 return DMA_MEM_TYPE_DMA;
1621 }
1622
1623 /* Technically, we could add one more classification. Addresses between VMALLOC_END */
1624 /* and the beginning of the DMA virtual address could be considered to be I/O space. */
1625 /* Right now, nobody cares about this particular classification, so we ignore it. */
1626
1627 if (is_vmalloc_addr(addr)) {
1628 /* Address comes from the vmalloc'd region. Pages are virtually */
1629 /* contiguous but NOT physically contiguous */
1630
1631 return DMA_MEM_TYPE_VMALLOC;
1632 }
1633
1634 if (addrVal >= PAGE_OFFSET) {
1635 /* PAGE_OFFSET is typically 0xC0000000 */
1636
1637 /* kmalloc'd pages are physically contiguous */
1638
1639 return DMA_MEM_TYPE_KMALLOC;
1640 }
1641
1642 return DMA_MEM_TYPE_USER;
1643}
1644
1645EXPORT_SYMBOL(dma_mem_type);
1646
1647/****************************************************************************/
1648/**
1649* Looks at a memory address and determines if we support DMA'ing to/from
1650* that type of memory.
1651*
1652* @return boolean -
1653* return value != 0 means dma supported
1654* return value == 0 means dma not supported
1655*/
1656/****************************************************************************/
1657
1658int dma_mem_supports_dma(void *addr)
1659{
1660 DMA_MemType_t memType = dma_mem_type(addr);
1661
1662 return (memType == DMA_MEM_TYPE_DMA)
1663#if ALLOW_MAP_OF_KMALLOC_MEMORY
1664 || (memType == DMA_MEM_TYPE_KMALLOC)
1665#endif
1666 || (memType == DMA_MEM_TYPE_USER);
1667}
1668
1669EXPORT_SYMBOL(dma_mem_supports_dma);
1670
1671/****************************************************************************/
1672/**
1673* Maps in a memory region such that it can be used for performing a DMA.
1674*
1675* @return
1676*/
1677/****************************************************************************/
1678
1679int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
1680 enum dma_data_direction dir /* Direction that the mapping will be going */
1681 ) {
1682 int rc;
1683
1684 down(&memMap->lock);
1685
1686 DMA_MAP_PRINT("memMap: %p\n", memMap);
1687
1688 if (memMap->inUse) {
1689 printk(KERN_ERR "%s: memory map %p is already being used\n",
1690 __func__, memMap);
1691 rc = -EBUSY;
1692 goto out;
1693 }
1694
1695 memMap->inUse = 1;
1696 memMap->dir = dir;
1697 memMap->numRegionsUsed = 0;
1698
1699 rc = 0;
1700
1701out:
1702
1703 DMA_MAP_PRINT("returning %d", rc);
1704
1705 up(&memMap->lock);
1706
1707 return rc;
1708}
1709
1710EXPORT_SYMBOL(dma_map_start);
1711
1712/****************************************************************************/
1713/**
1714* Adds a segment of memory to a memory map. Each segment is both
1715* physically and virtually contiguous.
1716*
1717* @return 0 on success, error code otherwise.
1718*/
1719/****************************************************************************/
1720
1721static int dma_map_add_segment(DMA_MemMap_t *memMap, /* Stores state information about the map */
1722 DMA_Region_t *region, /* Region that the segment belongs to */
1723 void *virtAddr, /* Virtual address of the segment being added */
1724 dma_addr_t physAddr, /* Physical address of the segment being added */
1725 size_t numBytes /* Number of bytes of the segment being added */
1726 ) {
1727 DMA_Segment_t *segment;
1728
1729 DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
1730 physAddr, numBytes);
1731
1732 /* Sanity check */
1733
1734 if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
1735 || (((unsigned long)virtAddr + numBytes)) >
1736 ((unsigned long)region->virtAddr + region->numBytes)) {
1737 printk(KERN_ERR
1738 "%s: virtAddr %p is outside region @ %p len: %d\n",
1739 __func__, virtAddr, region->virtAddr, region->numBytes);
1740 return -EINVAL;
1741 }
1742
1743 if (region->numSegmentsUsed > 0) {
1744 /* Check to see if this segment is physically contiguous with the previous one */
1745
1746 segment = &region->segment[region->numSegmentsUsed - 1];
1747
1748 if ((segment->physAddr + segment->numBytes) == physAddr) {
1749 /* It is - just add on to the end */
1750
1751 DMA_MAP_PRINT("appending %d bytes to last segment\n",
1752 numBytes);
1753
1754 segment->numBytes += numBytes;
1755
1756 return 0;
1757 }
1758 }
1759
1760 /* Reallocate to hold more segments, if required. */
1761
1762 if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
1763 DMA_Segment_t *newSegment;
1764 size_t oldSize =
1765 region->numSegmentsAllocated * sizeof(*newSegment);
1766 int newAlloc = region->numSegmentsAllocated + 4;
1767 size_t newSize = newAlloc * sizeof(*newSegment);
1768
1769 newSegment = kmalloc(newSize, GFP_KERNEL);
1770 if (newSegment == NULL) {
1771 return -ENOMEM;
1772 }
1773 memcpy(newSegment, region->segment, oldSize);
1774 memset(&((uint8_t *) newSegment)[oldSize], 0,
1775 newSize - oldSize);
1776 kfree(region->segment);
1777
1778 region->numSegmentsAllocated = newAlloc;
1779 region->segment = newSegment;
1780 }
1781
1782 segment = &region->segment[region->numSegmentsUsed];
1783 region->numSegmentsUsed++;
1784
1785 segment->virtAddr = virtAddr;
1786 segment->physAddr = physAddr;
1787 segment->numBytes = numBytes;
1788
1789 DMA_MAP_PRINT("returning success\n");
1790
1791 return 0;
1792}
1793
1794/****************************************************************************/
1795/**
1796* Adds a region of memory to a memory map. Each region is virtually
1797* contiguous, but not necessarily physically contiguous.
1798*
1799* @return 0 on success, error code otherwise.
1800*/
1801/****************************************************************************/
1802
1803int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
1804 void *mem, /* Virtual address that we want to get a map of */
1805 size_t numBytes /* Number of bytes being mapped */
1806 ) {
1807 unsigned long addr = (unsigned long)mem;
1808 unsigned int offset;
1809 int rc = 0;
1810 DMA_Region_t *region;
1811 dma_addr_t physAddr;
1812
1813 down(&memMap->lock);
1814
1815 DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
1816
1817 if (!memMap->inUse) {
1818 printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
1819 __func__);
1820 rc = -EINVAL;
1821 goto out;
1822 }
1823
1824 /* Reallocate to hold more regions. */
1825
1826 if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
1827 DMA_Region_t *newRegion;
1828 size_t oldSize =
1829 memMap->numRegionsAllocated * sizeof(*newRegion);
1830 int newAlloc = memMap->numRegionsAllocated + 4;
1831 size_t newSize = newAlloc * sizeof(*newRegion);
1832
1833 newRegion = kmalloc(newSize, GFP_KERNEL);
1834 if (newRegion == NULL) {
1835 rc = -ENOMEM;
1836 goto out;
1837 }
1838 memcpy(newRegion, memMap->region, oldSize);
1839 memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
1840
1841 kfree(memMap->region);
1842
1843 memMap->numRegionsAllocated = newAlloc;
1844 memMap->region = newRegion;
1845 }
1846
1847 region = &memMap->region[memMap->numRegionsUsed];
1848 memMap->numRegionsUsed++;
1849
1850 offset = addr & ~PAGE_MASK;
1851
1852 region->memType = dma_mem_type(mem);
1853 region->virtAddr = mem;
1854 region->numBytes = numBytes;
1855 region->numSegmentsUsed = 0;
1856 region->numLockedPages = 0;
1857 region->lockedPages = NULL;
1858
1859 switch (region->memType) {
1860 case DMA_MEM_TYPE_VMALLOC:
1861 {
1862 atomic_inc(&gDmaStatMemTypeVmalloc);
1863
1864 /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
1865
1866 /* vmalloc'd pages are not physically contiguous */
1867
1868 rc = -EINVAL;
1869 break;
1870 }
1871
1872 case DMA_MEM_TYPE_KMALLOC:
1873 {
1874 atomic_inc(&gDmaStatMemTypeKmalloc);
1875
1876 /* kmalloc'd pages are physically contiguous, so they'll have exactly */
1877 /* one segment */
1878
1879#if ALLOW_MAP_OF_KMALLOC_MEMORY
1880 physAddr =
1881 dma_map_single(NULL, mem, numBytes, memMap->dir);
1882 rc = dma_map_add_segment(memMap, region, mem, physAddr,
1883 numBytes);
1884#else
1885 rc = -EINVAL;
1886#endif
1887 break;
1888 }
1889
1890 case DMA_MEM_TYPE_DMA:
1891 {
1892 /* dma_alloc_xxx pages are physically contiguous */
1893
1894 atomic_inc(&gDmaStatMemTypeCoherent);
1895
1896 physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
1897
1898 dma_sync_single_for_cpu(NULL, physAddr, numBytes,
1899 memMap->dir);
1900 rc = dma_map_add_segment(memMap, region, mem, physAddr,
1901 numBytes);
1902 break;
1903 }
1904
1905 case DMA_MEM_TYPE_USER:
1906 {
1907 size_t firstPageOffset;
1908 size_t firstPageSize;
1909 struct page **pages;
1910 struct task_struct *userTask;
1911
1912 atomic_inc(&gDmaStatMemTypeUser);
1913
1914#if 1
1915 /* If the pages are user pages, then the dma_mem_map_set_user_task function */
1916 /* must have been previously called. */
1917
1918 if (memMap->userTask == NULL) {
1919 printk(KERN_ERR
1920 "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
1921 __func__);
1922 return -EINVAL;
1923 }
1924
1925 /* User pages need to be locked. */
1926
1927 firstPageOffset =
1928 (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
1929 firstPageSize = PAGE_SIZE - firstPageOffset;
1930
1931 region->numLockedPages = (firstPageOffset
1932 + region->numBytes +
1933 PAGE_SIZE - 1) / PAGE_SIZE;
1934 pages =
1935 kmalloc(region->numLockedPages *
1936 sizeof(struct page *), GFP_KERNEL);
1937
1938 if (pages == NULL) {
1939 region->numLockedPages = 0;
1940 return -ENOMEM;
1941 }
1942
1943 userTask = memMap->userTask;
1944
1945 down_read(&userTask->mm->mmap_sem);
1946 rc = get_user_pages(userTask, /* task */
1947 userTask->mm, /* mm */
1948 (unsigned long)region->virtAddr, /* start */
1949 region->numLockedPages, /* len */
1950 memMap->dir == DMA_FROM_DEVICE, /* write */
1951 0, /* force */
1952 pages, /* pages (array of pointers to page) */
1953 NULL); /* vmas */
1954 up_read(&userTask->mm->mmap_sem);
1955
1956 if (rc != region->numLockedPages) {
1957 kfree(pages);
1958 region->numLockedPages = 0;
1959
1960 if (rc >= 0) {
1961 rc = -EINVAL;
1962 }
1963 } else {
1964 uint8_t *virtAddr = region->virtAddr;
1965 size_t bytesRemaining;
1966 int pageIdx;
1967
1968 rc = 0; /* Since get_user_pages returns +ve number */
1969
1970 region->lockedPages = pages;
1971
1972 /* We've locked the user pages. Now we need to walk them and figure */
1973 /* out the physical addresses. */
1974
1975 /* The first page may be partial */
1976
1977 dma_map_add_segment(memMap,
1978 region,
1979 virtAddr,
1980 PFN_PHYS(page_to_pfn
1981 (pages[0])) +
1982 firstPageOffset,
1983 firstPageSize);
1984
1985 virtAddr += firstPageSize;
1986 bytesRemaining =
1987 region->numBytes - firstPageSize;
1988
1989 for (pageIdx = 1;
1990 pageIdx < region->numLockedPages;
1991 pageIdx++) {
1992 size_t bytesThisPage =
1993 (bytesRemaining >
1994 PAGE_SIZE ? PAGE_SIZE :
1995 bytesRemaining);
1996
1997 DMA_MAP_PRINT
1998 ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
1999 pageIdx, pages[pageIdx],
2000 page_to_pfn(pages[pageIdx]),
2001 PFN_PHYS(page_to_pfn
2002 (pages[pageIdx])));
2003
2004 dma_map_add_segment(memMap,
2005 region,
2006 virtAddr,
2007 PFN_PHYS(page_to_pfn
2008 (pages
2009 [pageIdx])),
2010 bytesThisPage);
2011
2012 virtAddr += bytesThisPage;
2013 bytesRemaining -= bytesThisPage;
2014 }
2015 }
2016#else
2017 printk(KERN_ERR
2018 "%s: User mode pages are not yet supported\n",
2019 __func__);
2020
2021 /* user pages are not physically contiguous */
2022
2023 rc = -EINVAL;
2024#endif
2025 break;
2026 }
2027
2028 default:
2029 {
2030 printk(KERN_ERR "%s: Unsupported memory type: %d\n",
2031 __func__, region->memType);
2032
2033 rc = -EINVAL;
2034 break;
2035 }
2036 }
2037
2038 if (rc != 0) {
2039 memMap->numRegionsUsed--;
2040 }
2041
2042out:
2043
2044 DMA_MAP_PRINT("returning %d\n", rc);
2045
2046 up(&memMap->lock);
2047
2048 return rc;
2049}
2050
2051EXPORT_SYMBOL(dma_map_add_segment);
2052
2053/****************************************************************************/
2054/**
2055* Maps in a memory region such that it can be used for performing a DMA.
2056*
2057* @return 0 on success, error code otherwise.
2058*/
2059/****************************************************************************/
2060
2061int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
2062 void *mem, /* Virtual address that we want to get a map of */
2063 size_t numBytes, /* Number of bytes being mapped */
2064 enum dma_data_direction dir /* Direction that the mapping will be going */
2065 ) {
2066 int rc;
2067
2068 rc = dma_map_start(memMap, dir);
2069 if (rc == 0) {
2070 rc = dma_map_add_region(memMap, mem, numBytes);
2071 if (rc < 0) {
2072 /* Since the add fails, this function will fail, and the caller won't */
2073 /* call unmap, so we need to do it here. */
2074
2075 dma_unmap(memMap, 0);
2076 }
2077 }
2078
2079 return rc;
2080}
2081
2082EXPORT_SYMBOL(dma_map_mem);
2083
2084/****************************************************************************/
2085/**
2086* Setup a descriptor ring for a given memory map.
2087*
2088* It is assumed that the descriptor ring has already been initialized, and
2089* this routine will only reallocate a new descriptor ring if the existing
2090* one is too small.
2091*
2092* @return 0 on success, error code otherwise.
2093*/
2094/****************************************************************************/
2095
2096int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
2097 DMA_MemMap_t *memMap, /* Memory map that will be used */
2098 dma_addr_t devPhysAddr /* Physical address of device */
2099 ) {
2100 int rc;
2101 int numDescriptors;
2102 DMA_DeviceAttribute_t *devAttr;
2103 DMA_Region_t *region;
2104 DMA_Segment_t *segment;
2105 dma_addr_t srcPhysAddr;
2106 dma_addr_t dstPhysAddr;
2107 int regionIdx;
2108 int segmentIdx;
2109
2110 devAttr = &DMA_gDeviceAttribute[dev];
2111
2112 down(&memMap->lock);
2113
2114 /* Figure out how many descriptors we need */
2115
2116 numDescriptors = 0;
2117 for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
2118 region = &memMap->region[regionIdx];
2119
2120 for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
2121 segmentIdx++) {
2122 segment = &region->segment[segmentIdx];
2123
2124 if (memMap->dir == DMA_TO_DEVICE) {
2125 srcPhysAddr = segment->physAddr;
2126 dstPhysAddr = devPhysAddr;
2127 } else {
2128 srcPhysAddr = devPhysAddr;
2129 dstPhysAddr = segment->physAddr;
2130 }
2131
2132 rc =
2133 dma_calculate_descriptor_count(dev, srcPhysAddr,
2134 dstPhysAddr,
2135 segment->
2136 numBytes);
2137 if (rc < 0) {
2138 printk(KERN_ERR
2139 "%s: dma_calculate_descriptor_count failed: %d\n",
2140 __func__, rc);
2141 goto out;
2142 }
2143 numDescriptors += rc;
2144 }
2145 }
2146
2147 /* Adjust the size of the ring, if it isn't big enough */
2148
2149 if (numDescriptors > devAttr->ring.descriptorsAllocated) {
2150 dma_free_descriptor_ring(&devAttr->ring);
2151 rc =
2152 dma_alloc_descriptor_ring(&devAttr->ring,
2153 numDescriptors);
2154 if (rc < 0) {
2155 printk(KERN_ERR
2156 "%s: dma_alloc_descriptor_ring failed: %d\n",
2157 __func__, rc);
2158 goto out;
2159 }
2160 } else {
2161 rc =
2162 dma_init_descriptor_ring(&devAttr->ring,
2163 numDescriptors);
2164 if (rc < 0) {
2165 printk(KERN_ERR
2166 "%s: dma_init_descriptor_ring failed: %d\n",
2167 __func__, rc);
2168 goto out;
2169 }
2170 }
2171
2172 /* Populate the descriptors */
2173
2174 for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
2175 region = &memMap->region[regionIdx];
2176
2177 for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
2178 segmentIdx++) {
2179 segment = &region->segment[segmentIdx];
2180
2181 if (memMap->dir == DMA_TO_DEVICE) {
2182 srcPhysAddr = segment->physAddr;
2183 dstPhysAddr = devPhysAddr;
2184 } else {
2185 srcPhysAddr = devPhysAddr;
2186 dstPhysAddr = segment->physAddr;
2187 }
2188
2189 rc =
2190 dma_add_descriptors(&devAttr->ring, dev,
2191 srcPhysAddr, dstPhysAddr,
2192 segment->numBytes);
2193 if (rc < 0) {
2194 printk(KERN_ERR
2195 "%s: dma_add_descriptors failed: %d\n",
2196 __func__, rc);
2197 goto out;
2198 }
2199 }
2200 }
2201
2202 rc = 0;
2203
2204out:
2205
2206 up(&memMap->lock);
2207 return rc;
2208}
2209
2210EXPORT_SYMBOL(dma_map_create_descriptor_ring);
2211
2212/****************************************************************************/
2213/**
2214* Maps in a memory region such that it can be used for performing a DMA.
2215*
2216* @return
2217*/
2218/****************************************************************************/
2219
2220int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
2221 int dirtied /* non-zero if any of the pages were modified */
2222 ) {
2223 int regionIdx;
2224 int segmentIdx;
2225 DMA_Region_t *region;
2226 DMA_Segment_t *segment;
2227
2228 for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
2229 region = &memMap->region[regionIdx];
2230
2231 for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
2232 segmentIdx++) {
2233 segment = &region->segment[segmentIdx];
2234
2235 switch (region->memType) {
2236 case DMA_MEM_TYPE_VMALLOC:
2237 {
2238 printk(KERN_ERR
2239 "%s: vmalloc'd pages are not yet supported\n",
2240 __func__);
2241 return -EINVAL;
2242 }
2243
2244 case DMA_MEM_TYPE_KMALLOC:
2245 {
2246#if ALLOW_MAP_OF_KMALLOC_MEMORY
2247 dma_unmap_single(NULL,
2248 segment->physAddr,
2249 segment->numBytes,
2250 memMap->dir);
2251#endif
2252 break;
2253 }
2254
2255 case DMA_MEM_TYPE_DMA:
2256 {
2257 dma_sync_single_for_cpu(NULL,
2258 segment->
2259 physAddr,
2260 segment->
2261 numBytes,
2262 memMap->dir);
2263 break;
2264 }
2265
2266 case DMA_MEM_TYPE_USER:
2267 {
2268 /* Nothing to do here. */
2269
2270 break;
2271 }
2272
2273 default:
2274 {
2275 printk(KERN_ERR
2276 "%s: Unsupported memory type: %d\n",
2277 __func__, region->memType);
2278 return -EINVAL;
2279 }
2280 }
2281
2282 segment->virtAddr = NULL;
2283 segment->physAddr = 0;
2284 segment->numBytes = 0;
2285 }
2286
2287 if (region->numLockedPages > 0) {
2288 int pageIdx;
2289
2290 /* Some user pages were locked. We need to go and unlock them now. */
2291
2292 for (pageIdx = 0; pageIdx < region->numLockedPages;
2293 pageIdx++) {
2294 struct page *page =
2295 region->lockedPages[pageIdx];
2296
2297 if (memMap->dir == DMA_FROM_DEVICE) {
2298 SetPageDirty(page);
2299 }
2300 page_cache_release(page);
2301 }
2302 kfree(region->lockedPages);
2303 region->numLockedPages = 0;
2304 region->lockedPages = NULL;
2305 }
2306
2307 region->memType = DMA_MEM_TYPE_NONE;
2308 region->virtAddr = NULL;
2309 region->numBytes = 0;
2310 region->numSegmentsUsed = 0;
2311 }
2312 memMap->userTask = NULL;
2313 memMap->numRegionsUsed = 0;
2314 memMap->inUse = 0;
2315
2316 up(&memMap->lock);
2317
2318 return 0;
2319}
2320
2321EXPORT_SYMBOL(dma_unmap);
diff --git a/arch/arm/mach-bcmring/dma_device.c b/arch/arm/mach-bcmring/dma_device.c
new file mode 100644
index 000000000000..ca0ad736870b
--- /dev/null
+++ b/arch/arm/mach-bcmring/dma_device.c
@@ -0,0 +1,593 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dma_device.c
18*
19* @brief private array of DMA_DeviceAttribute_t
20*/
21/****************************************************************************/
22
23DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES] = {
24 [DMA_DEVICE_MEM_TO_MEM] = /* MEM 2 MEM */
25 {
26 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
27 .name = "mem-to-mem",
28 .config = {
29 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
30 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
31 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
32 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
33 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
34 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
35 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
36 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
37 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
38 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
39 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
40
41 },
42 },
43 [DMA_DEVICE_VPM_MEM_TO_MEM] = /* VPM */
44 {
45 .flags = DMA_DEVICE_FLAG_IS_DEDICATED | DMA_DEVICE_FLAG_NO_ISR,
46 .name = "vpm",
47 .dedicatedController = 0,
48 .dedicatedChannel = 0,
49 /* reserve DMA0:0 for VPM */
50 },
51 [DMA_DEVICE_NAND_MEM_TO_MEM] = /* NAND */
52 {
53 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
54 .name = "nand",
55 .config = {
56 .srcPeripheralPort = 0,
57 .dstPeripheralPort = 0,
58 .srcStatusRegisterAddress = 0x00000000,
59 .dstStatusRegisterAddress = 0x00000000,
60 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
61 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
62 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
63 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
64 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
65 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
66 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
67 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
68 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
69 .channelPriority = dmacHw_CHANNEL_PRIORITY_6,
70 },
71 },
72 [DMA_DEVICE_PIF_MEM_TO_DEV] = /* PIF TX */
73 {
74 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1
75 | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO
76 | DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST | DMA_DEVICE_FLAG_PORT_PER_DMAC,
77 .name = "pif_tx",
78 .dmacPort = {14, 5},
79 .config = {
80 .srcPeripheralPort = 0, /* SRC: memory */
81 /* dstPeripheralPort = 5 or 14 */
82 .srcStatusRegisterAddress = 0x00000000,
83 .dstStatusRegisterAddress = 0x00000000,
84 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
85 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
86 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
87 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
88 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
89 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
90 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
91 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
92 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
93 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
94 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
95 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
96 .maxDataPerBlock = 16256,
97 },
98 },
99 [DMA_DEVICE_PIF_DEV_TO_MEM] = /* PIF RX */
100 {
101 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1
102 | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO
103 /* DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST */
104 | DMA_DEVICE_FLAG_PORT_PER_DMAC,
105 .name = "pif_rx",
106 .dmacPort = {14, 5},
107 .config = {
108 /* srcPeripheralPort = 5 or 14 */
109 .dstPeripheralPort = 0, /* DST: memory */
110 .srcStatusRegisterAddress = 0x00000000,
111 .dstStatusRegisterAddress = 0x00000000,
112 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
113 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
114 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
115 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
116 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
117 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
118 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
119 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
120 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
121 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
122 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
123 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
124 .maxDataPerBlock = 16256,
125 },
126 },
127 [DMA_DEVICE_I2S0_DEV_TO_MEM] = /* I2S RX */
128 {
129 .flags = DMA_DEVICE_FLAG_ON_DMA0,
130 .name = "i2s0_rx",
131 .config = {
132 .srcPeripheralPort = 0, /* SRC: I2S0 */
133 .dstPeripheralPort = 0, /* DST: memory */
134 .srcStatusRegisterAddress = 0,
135 .dstStatusRegisterAddress = 0,
136 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
137 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
138 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
139 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16,
140 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
141 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
142 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
143 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
144 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
145 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
146 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
147 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
148 },
149 },
150 [DMA_DEVICE_I2S0_MEM_TO_DEV] = /* I2S TX */
151 {
152 .flags = DMA_DEVICE_FLAG_ON_DMA0,
153 .name = "i2s0_tx",
154 .config = {
155 .srcPeripheralPort = 0, /* SRC: memory */
156 .dstPeripheralPort = 1, /* DST: I2S0 */
157 .srcStatusRegisterAddress = 0,
158 .dstStatusRegisterAddress = 0,
159 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
160 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
161 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
162 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
163 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16,
164 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
165 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
166 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
167 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
168 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
169 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
170 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
171 },
172 },
173 [DMA_DEVICE_I2S1_DEV_TO_MEM] = /* I2S1 RX */
174 {
175 .flags = DMA_DEVICE_FLAG_ON_DMA1,
176 .name = "i2s1_rx",
177 .config = {
178 .srcPeripheralPort = 2, /* SRC: I2S1 */
179 .dstPeripheralPort = 0, /* DST: memory */
180 .srcStatusRegisterAddress = 0,
181 .dstStatusRegisterAddress = 0,
182 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
183 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
184 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
185 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16,
186 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
187 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
188 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
189 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
190 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
191 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
192 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
193 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
194 },
195 },
196 [DMA_DEVICE_I2S1_MEM_TO_DEV] = /* I2S1 TX */
197 {
198 .flags = DMA_DEVICE_FLAG_ON_DMA1,
199 .name = "i2s1_tx",
200 .config = {
201 .srcPeripheralPort = 0, /* SRC: memory */
202 .dstPeripheralPort = 3, /* DST: I2S1 */
203 .srcStatusRegisterAddress = 0,
204 .dstStatusRegisterAddress = 0,
205 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
206 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
207 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
208 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
209 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16,
210 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
211 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
212 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
213 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
214 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
215 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
216 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
217 },
218 },
219 [DMA_DEVICE_ESW_MEM_TO_DEV] = /* ESW TX */
220 {
221 .name = "esw_tx",
222 .flags = DMA_DEVICE_FLAG_IS_DEDICATED,
223 .dedicatedController = 1,
224 .dedicatedChannel = 3,
225 .config = {
226 .srcPeripheralPort = 0, /* SRC: memory */
227 .dstPeripheralPort = 1, /* DST: ESW (MTP) */
228 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
229 .errorInterrupt = dmacHw_INTERRUPT_DISABLE,
230 /* DMAx_AHB_SSTATARy */
231 .srcStatusRegisterAddress = 0x00000000,
232 /* DMAx_AHB_DSTATARy */
233 .dstStatusRegisterAddress = 0x30490010,
234 /* DMAx_AHB_CFGy */
235 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
236 /* DMAx_AHB_CTLy */
237 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
238 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
239 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
240 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
241 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
242 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
243 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
244 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
245 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
246 },
247 },
248 [DMA_DEVICE_ESW_DEV_TO_MEM] = /* ESW RX */
249 {
250 .name = "esw_rx",
251 .flags = DMA_DEVICE_FLAG_IS_DEDICATED,
252 .dedicatedController = 1,
253 .dedicatedChannel = 2,
254 .config = {
255 .srcPeripheralPort = 0, /* SRC: ESW (PTM) */
256 .dstPeripheralPort = 0, /* DST: memory */
257 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
258 .errorInterrupt = dmacHw_INTERRUPT_DISABLE,
259 /* DMAx_AHB_SSTATARy */
260 .srcStatusRegisterAddress = 0x30480010,
261 /* DMAx_AHB_DSTATARy */
262 .dstStatusRegisterAddress = 0x00000000,
263 /* DMAx_AHB_CFGy */
264 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
265 /* DMAx_AHB_CTLy */
266 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
267 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
268 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
269 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
270 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
271 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
272 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
273 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
274 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
275 },
276 },
277 [DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM] = /* APM Codec A Ingress */
278 {
279 .flags = DMA_DEVICE_FLAG_ON_DMA0,
280 .name = "apm_a_rx",
281 .config = {
282 .srcPeripheralPort = 2, /* SRC: Codec A Ingress FIFO */
283 .dstPeripheralPort = 0, /* DST: memory */
284 .srcStatusRegisterAddress = 0x00000000,
285 .dstStatusRegisterAddress = 0x00000000,
286 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
287 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
288 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
289 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
290 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
291 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
292 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
293 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
294 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
295 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
296 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
297 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
298 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
299 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
300 },
301 },
302 [DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV] = /* APM Codec A Egress */
303 {
304 .flags = DMA_DEVICE_FLAG_ON_DMA0,
305 .name = "apm_a_tx",
306 .config = {
307 .srcPeripheralPort = 0, /* SRC: memory */
308 .dstPeripheralPort = 3, /* DST: Codec A Egress FIFO */
309 .srcStatusRegisterAddress = 0x00000000,
310 .dstStatusRegisterAddress = 0x00000000,
311 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
312 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
313 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
314 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
315 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
316 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
317 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
318 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
319 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
320 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
321 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
322 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
323 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
324 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
325 },
326 },
327 [DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM] = /* APM Codec B Ingress */
328 {
329 .flags = DMA_DEVICE_FLAG_ON_DMA0,
330 .name = "apm_b_rx",
331 .config = {
332 .srcPeripheralPort = 4, /* SRC: Codec B Ingress FIFO */
333 .dstPeripheralPort = 0, /* DST: memory */
334 .srcStatusRegisterAddress = 0x00000000,
335 .dstStatusRegisterAddress = 0x00000000,
336 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
337 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
338 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
339 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
340 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
341 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
342 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
343 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
344 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
345 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
346 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
347 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
348 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
349 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
350 },
351 },
352 [DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV] = /* APM Codec B Egress */
353 {
354 .flags = DMA_DEVICE_FLAG_ON_DMA0,
355 .name = "apm_b_tx",
356 .config = {
357 .srcPeripheralPort = 0, /* SRC: memory */
358 .dstPeripheralPort = 5, /* DST: Codec B Egress FIFO */
359 .srcStatusRegisterAddress = 0x00000000,
360 .dstStatusRegisterAddress = 0x00000000,
361 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
362 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
363 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
364 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
365 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
366 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
367 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
368 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
369 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
370 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
371 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
372 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
373 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
374 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
375 },
376 },
377 [DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM] = /* APM Codec C Ingress */
378 {
379 .flags = DMA_DEVICE_FLAG_ON_DMA1,
380 .name = "apm_c_rx",
381 .config = {
382 .srcPeripheralPort = 4, /* SRC: Codec C Ingress FIFO */
383 .dstPeripheralPort = 0, /* DST: memory */
384 .srcStatusRegisterAddress = 0x00000000,
385 .dstStatusRegisterAddress = 0x00000000,
386 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
387 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
388 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
389 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
390 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
391 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
392 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
393 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
394 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
395 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
396 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
397 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
398 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
399 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
400 },
401 },
402 [DMA_DEVICE_APM_PCM0_DEV_TO_MEM] = /* PCM0 RX */
403 {
404 .flags = DMA_DEVICE_FLAG_ON_DMA0,
405 .name = "pcm0_rx",
406 .config = {
407 .srcPeripheralPort = 12, /* SRC: PCM0 */
408 .dstPeripheralPort = 0, /* DST: memory */
409 .srcStatusRegisterAddress = 0,
410 .dstStatusRegisterAddress = 0,
411 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
412 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
413 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
414 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
415 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
416 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
417 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
418 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
419 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
420 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
421 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
422 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
423 },
424 },
425 [DMA_DEVICE_APM_PCM0_MEM_TO_DEV] = /* PCM0 TX */
426 {
427 .flags = DMA_DEVICE_FLAG_ON_DMA0,
428 .name = "pcm0_tx",
429 .config = {
430 .srcPeripheralPort = 0, /* SRC: memory */
431 .dstPeripheralPort = 13, /* DST: PCM0 */
432 .srcStatusRegisterAddress = 0,
433 .dstStatusRegisterAddress = 0,
434 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
435 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
436 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
437 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
438 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
439 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
440 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
441 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
442 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
443 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
444 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
445 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
446 },
447 },
448 [DMA_DEVICE_APM_PCM1_DEV_TO_MEM] = /* PCM1 RX */
449 {
450 .flags = DMA_DEVICE_FLAG_ON_DMA1,
451 .name = "pcm1_rx",
452 .config = {
453 .srcPeripheralPort = 14, /* SRC: PCM1 */
454 .dstPeripheralPort = 0, /* DST: memory */
455 .srcStatusRegisterAddress = 0,
456 .dstStatusRegisterAddress = 0,
457 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
458 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
459 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
460 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
461 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
462 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
463 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
464 .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
465 .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
466 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
467 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
468 .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
469 },
470 },
471 [DMA_DEVICE_APM_PCM1_MEM_TO_DEV] = /* PCM1 TX */
472 {
473 .flags = DMA_DEVICE_FLAG_ON_DMA1,
474 .name = "pcm1_tx",
475 .config = {
476 .srcPeripheralPort = 0, /* SRC: memory */
477 .dstPeripheralPort = 15, /* DST: PCM1 */
478 .srcStatusRegisterAddress = 0,
479 .dstStatusRegisterAddress = 0,
480 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
481 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
482 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
483 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
484 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
485 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
486 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
487 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
488 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
489 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
490 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
491 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
492 },
493 },
494 [DMA_DEVICE_SPUM_DEV_TO_MEM] = /* SPUM RX */
495 {
496 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
497 .name = "spum_rx",
498 .config = {
499 .srcPeripheralPort = 6, /* SRC: Codec A Ingress FIFO */
500 .dstPeripheralPort = 0, /* DST: memory */
501 .srcStatusRegisterAddress = 0x00000000,
502 .dstStatusRegisterAddress = 0x00000000,
503 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
504 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
505 .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
506 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
507 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
508 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
509 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
510 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
511 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
512 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
513 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
514 /* Busrt size **MUST** be 16 for SPUM to work */
515 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16,
516 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16,
517 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
518 /* on the RX side, SPU needs to be the flow controller */
519 .flowControler = dmacHw_FLOW_CONTROL_PERIPHERAL,
520 },
521 },
522 [DMA_DEVICE_SPUM_MEM_TO_DEV] = /* SPUM TX */
523 {
524 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
525 .name = "spum_tx",
526 .config = {
527 .srcPeripheralPort = 0, /* SRC: memory */
528 .dstPeripheralPort = 7, /* DST: SPUM */
529 .srcStatusRegisterAddress = 0x00000000,
530 .dstStatusRegisterAddress = 0x00000000,
531 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
532 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
533 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
534 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
535 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
536 .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
537 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
538 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
539 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
540 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
541 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
542 /* Busrt size **MUST** be 16 for SPUM to work */
543 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16,
544 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16,
545 .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
546 },
547 },
548 [DMA_DEVICE_MEM_TO_VRAM] = /* MEM 2 VRAM */
549 {
550 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
551 .name = "mem-to-vram",
552 .config = {
553 .srcPeripheralPort = 0, /* SRC: memory */
554 .srcStatusRegisterAddress = 0x00000000,
555 .dstStatusRegisterAddress = 0x00000000,
556 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
557 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
558 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
559 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
560 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
561 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
562 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
563 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
564 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
565 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
566 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
567 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
568 },
569 },
570 [DMA_DEVICE_VRAM_TO_MEM] = /* VRAM 2 MEM */
571 {
572 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
573 .name = "vram-to-mem",
574 .config = {
575 .dstPeripheralPort = 0, /* DST: memory */
576 .srcStatusRegisterAddress = 0x00000000,
577 .dstStatusRegisterAddress = 0x00000000,
578 .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
579 .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
580 .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
581 .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
582 .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
583 .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
584 .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
585 .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
586 .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
587 .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
588 .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
589 .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
590 },
591 },
592};
593EXPORT_SYMBOL(DMA_gDeviceAttribute); /* primarily for dma-test.c */
diff --git a/arch/arm/mach-bcmring/include/cfg_global.h b/arch/arm/mach-bcmring/include/cfg_global.h
new file mode 100644
index 000000000000..f01da877148e
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/cfg_global.h
@@ -0,0 +1,13 @@
1#ifndef _CFG_GLOBAL_H_
2#define _CFG_GLOBAL_H_
3
4#include <cfg_global_defines.h>
5
6#define CFG_GLOBAL_CHIP BCM11107
7#define CFG_GLOBAL_CHIP_FAMILY CFG_GLOBAL_CHIP_FAMILY_BCMRING
8#define CFG_GLOBAL_CHIP_REV 0xB0
9#define CFG_GLOBAL_RAM_SIZE 0x10000000
10#define CFG_GLOBAL_RAM_BASE 0x00000000
11#define CFG_GLOBAL_RAM_RESERVED_SIZE 0x000000
12
13#endif /* _CFG_GLOBAL_H_ */
diff --git a/arch/arm/mach-bcmring/include/cfg_global_defines.h b/arch/arm/mach-bcmring/include/cfg_global_defines.h
new file mode 100644
index 000000000000..b5beb0b30734
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/cfg_global_defines.h
@@ -0,0 +1,40 @@
1/*****************************************************************************
2* Copyright 2006 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CFG_GLOBAL_DEFINES_H
16#define CFG_GLOBAL_DEFINES_H
17
18/* CHIP */
19#define BCM1103 1
20
21#define BCM1191 4
22#define BCM2153 5
23#define BCM2820 6
24
25#define BCM2826 8
26#define FPGA11107 9
27#define BCM11107 10
28#define BCM11109 11
29#define BCM11170 12
30#define BCM11110 13
31#define BCM11211 14
32
33/* CFG_GLOBAL_CHIP_FAMILY types */
34#define CFG_GLOBAL_CHIP_FAMILY_NONE 0
35#define CFG_GLOBAL_CHIP_FAMILY_BCM116X 2
36#define CFG_GLOBAL_CHIP_FAMILY_BCMRING 4
37#define CFG_GLOBAL_CHIP_FAMILY_BCM1103 8
38
39#define IMAGE_HEADER_SIZE_CHECKSUM 4
40#endif
diff --git a/arch/arm/mach-bcmring/include/csp/cache.h b/arch/arm/mach-bcmring/include/csp/cache.h
new file mode 100644
index 000000000000..caa20e59db99
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/cache.h
@@ -0,0 +1,35 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CSP_CACHE_H
16#define CSP_CACHE_H
17
18/* ---- Include Files ---------------------------------------------------- */
19
20#include <csp/stdint.h>
21
22/* ---- Public Constants and Types --------------------------------------- */
23
24#if defined(__KERNEL__) && !defined(STANDALONE)
25#include <asm/cacheflush.h>
26
27#define CSP_CACHE_FLUSH_ALL flush_cache_all()
28
29#else
30
31#define CSP_CACHE_FLUSH_ALL
32
33#endif
34
35#endif /* CSP_CACHE_H */
diff --git a/arch/arm/mach-bcmring/include/csp/delay.h b/arch/arm/mach-bcmring/include/csp/delay.h
new file mode 100644
index 000000000000..8b3d80367293
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/delay.h
@@ -0,0 +1,36 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15
16#ifndef CSP_DELAY_H
17#define CSP_DELAY_H
18
19/* ---- Include Files ---------------------------------------------------- */
20
21/* Some CSP routines require use of the following delay routines. Use the OS */
22/* version if available, otherwise use a CSP specific definition. */
23/* void udelay(unsigned long usecs); */
24/* void mdelay(unsigned long msecs); */
25
26#if defined(__KERNEL__) && !defined(STANDALONE)
27 #include <linux/delay.h>
28#else
29 #include <mach/csp/delay.h>
30#endif
31
32/* ---- Public Constants and Types --------------------------------------- */
33/* ---- Public Variable Externs ------------------------------------------ */
34/* ---- Public Function Prototypes --------------------------------------- */
35
36#endif /* CSP_DELAY_H */
diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h
new file mode 100644
index 000000000000..5d510130a25f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h
@@ -0,0 +1,596 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dmacHw.h
18*
19* @brief API definitions for low level DMA controller driver
20*
21*/
22/****************************************************************************/
23#ifndef _DMACHW_H
24#define _DMACHW_H
25
26#include <stddef.h>
27
28#include <csp/stdint.h>
29#include <mach/csp/dmacHw_reg.h>
30
31/* Define DMA Channel ID using DMA controller number (m) and channel number (c).
32
33 System specific channel ID should be defined as follows
34
35 For example:
36
37 #include <dmacHw.h>
38 ...
39 #define systemHw_LCD_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,5)
40 #define systemHw_SWITCH_RX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,0)
41 #define systemHw_SWITCH_TX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,1)
42 #define systemHw_APM_RX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,3)
43 #define systemHw_APM_TX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,4)
44 ...
45 #define systemHw_SHARED1_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(1,4)
46 #define systemHw_SHARED2_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(1,5)
47 #define systemHw_SHARED3_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,6)
48 ...
49*/
50#define dmacHw_MAKE_CHANNEL_ID(m, c) (m << 8 | c)
51
52typedef enum {
53 dmacHw_CHANNEL_PRIORITY_0 = dmacHw_REG_CFG_LO_CH_PRIORITY_0, /* Channel priority 0. Lowest priority DMA channel */
54 dmacHw_CHANNEL_PRIORITY_1 = dmacHw_REG_CFG_LO_CH_PRIORITY_1, /* Channel priority 1 */
55 dmacHw_CHANNEL_PRIORITY_2 = dmacHw_REG_CFG_LO_CH_PRIORITY_2, /* Channel priority 2 */
56 dmacHw_CHANNEL_PRIORITY_3 = dmacHw_REG_CFG_LO_CH_PRIORITY_3, /* Channel priority 3 */
57 dmacHw_CHANNEL_PRIORITY_4 = dmacHw_REG_CFG_LO_CH_PRIORITY_4, /* Channel priority 4 */
58 dmacHw_CHANNEL_PRIORITY_5 = dmacHw_REG_CFG_LO_CH_PRIORITY_5, /* Channel priority 5 */
59 dmacHw_CHANNEL_PRIORITY_6 = dmacHw_REG_CFG_LO_CH_PRIORITY_6, /* Channel priority 6 */
60 dmacHw_CHANNEL_PRIORITY_7 = dmacHw_REG_CFG_LO_CH_PRIORITY_7 /* Channel priority 7. Highest priority DMA channel */
61} dmacHw_CHANNEL_PRIORITY_e;
62
63/* Source destination master interface */
64typedef enum {
65 dmacHw_SRC_MASTER_INTERFACE_1 = dmacHw_REG_CTL_SMS_1, /* Source DMA master interface 1 */
66 dmacHw_SRC_MASTER_INTERFACE_2 = dmacHw_REG_CTL_SMS_2, /* Source DMA master interface 2 */
67 dmacHw_DST_MASTER_INTERFACE_1 = dmacHw_REG_CTL_DMS_1, /* Destination DMA master interface 1 */
68 dmacHw_DST_MASTER_INTERFACE_2 = dmacHw_REG_CTL_DMS_2 /* Destination DMA master interface 2 */
69} dmacHw_MASTER_INTERFACE_e;
70
71typedef enum {
72 dmacHw_SRC_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_SRC_TR_WIDTH_8, /* Source 8 bit (1 byte) per transaction */
73 dmacHw_SRC_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_SRC_TR_WIDTH_16, /* Source 16 bit (2 byte) per transaction */
74 dmacHw_SRC_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_SRC_TR_WIDTH_32, /* Source 32 bit (4 byte) per transaction */
75 dmacHw_SRC_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_SRC_TR_WIDTH_64, /* Source 64 bit (8 byte) per transaction */
76 dmacHw_DST_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_DST_TR_WIDTH_8, /* Destination 8 bit (1 byte) per transaction */
77 dmacHw_DST_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_DST_TR_WIDTH_16, /* Destination 16 bit (2 byte) per transaction */
78 dmacHw_DST_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_DST_TR_WIDTH_32, /* Destination 32 bit (4 byte) per transaction */
79 dmacHw_DST_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_DST_TR_WIDTH_64 /* Destination 64 bit (8 byte) per transaction */
80} dmacHw_TRANSACTION_WIDTH_e;
81
82typedef enum {
83 dmacHw_SRC_BURST_WIDTH_0 = dmacHw_REG_CTL_SRC_MSIZE_0, /* Source No burst */
84 dmacHw_SRC_BURST_WIDTH_4 = dmacHw_REG_CTL_SRC_MSIZE_4, /* Source 4 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
85 dmacHw_SRC_BURST_WIDTH_8 = dmacHw_REG_CTL_SRC_MSIZE_8, /* Source 8 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
86 dmacHw_SRC_BURST_WIDTH_16 = dmacHw_REG_CTL_SRC_MSIZE_16, /* Source 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
87 dmacHw_DST_BURST_WIDTH_0 = dmacHw_REG_CTL_DST_MSIZE_0, /* Destination No burst */
88 dmacHw_DST_BURST_WIDTH_4 = dmacHw_REG_CTL_DST_MSIZE_4, /* Destination 4 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
89 dmacHw_DST_BURST_WIDTH_8 = dmacHw_REG_CTL_DST_MSIZE_8, /* Destination 8 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
90 dmacHw_DST_BURST_WIDTH_16 = dmacHw_REG_CTL_DST_MSIZE_16 /* Destination 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
91} dmacHw_BURST_WIDTH_e;
92
93typedef enum {
94 dmacHw_TRANSFER_TYPE_MEM_TO_MEM = dmacHw_REG_CTL_TTFC_MM_DMAC, /* Memory to memory transfer */
95 dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM = dmacHw_REG_CTL_TTFC_PM_DMAC, /* Peripheral to memory transfer */
96 dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_MP_DMAC, /* Memory to peripheral transfer */
97 dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_PP_DMAC /* Peripheral to peripheral transfer */
98} dmacHw_TRANSFER_TYPE_e;
99
100typedef enum {
101 dmacHw_TRANSFER_MODE_PERREQUEST, /* Block transfer per DMA request */
102 dmacHw_TRANSFER_MODE_CONTINUOUS, /* Continuous transfer of streaming data */
103 dmacHw_TRANSFER_MODE_PERIODIC /* Periodic transfer of streaming data */
104} dmacHw_TRANSFER_MODE_e;
105
106typedef enum {
107 dmacHw_SRC_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_SINC_INC, /* Increment source address after every transaction */
108 dmacHw_SRC_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_SINC_DEC, /* Decrement source address after every transaction */
109 dmacHw_DST_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_DINC_INC, /* Increment destination address after every transaction */
110 dmacHw_DST_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_DINC_DEC, /* Decrement destination address after every transaction */
111 dmacHw_SRC_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_SINC_NC, /* No change in source address after every transaction */
112 dmacHw_DST_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_DINC_NC /* No change in destination address after every transaction */
113} dmacHw_ADDRESS_UPDATE_MODE_e;
114
115typedef enum {
116 dmacHw_FLOW_CONTROL_DMA, /* DMA working as flow controller (default) */
117 dmacHw_FLOW_CONTROL_PERIPHERAL /* Peripheral working as flow controller */
118} dmacHw_FLOW_CONTROL_e;
119
120typedef enum {
121 dmacHw_TRANSFER_STATUS_BUSY, /* DMA Transfer ongoing */
122 dmacHw_TRANSFER_STATUS_DONE, /* DMA Transfer completed */
123 dmacHw_TRANSFER_STATUS_ERROR /* DMA Transfer error */
124} dmacHw_TRANSFER_STATUS_e;
125
126typedef enum {
127 dmacHw_INTERRUPT_DISABLE, /* Interrupt disable */
128 dmacHw_INTERRUPT_ENABLE /* Interrupt enable */
129} dmacHw_INTERRUPT_e;
130
131typedef enum {
132 dmacHw_INTERRUPT_STATUS_NONE = 0x0, /* No DMA interrupt */
133 dmacHw_INTERRUPT_STATUS_TRANS = 0x1, /* End of DMA transfer interrupt */
134 dmacHw_INTERRUPT_STATUS_BLOCK = 0x2, /* End of block transfer interrupt */
135 dmacHw_INTERRUPT_STATUS_ERROR = 0x4 /* Error interrupt */
136} dmacHw_INTERRUPT_STATUS_e;
137
138typedef enum {
139 dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM, /* Number of DMA channel */
140 dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE, /* Maximum channel burst size */
141 dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM, /* Number of DMA master interface */
142 dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH, /* Channel Data bus width */
143 dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE /* Channel FIFO size */
144} dmacHw_CONTROLLER_ATTRIB_e;
145
146typedef unsigned long dmacHw_HANDLE_t; /* DMA channel handle */
147typedef uint32_t dmacHw_ID_t; /* DMA channel Id. Must be created using
148 "dmacHw_MAKE_CHANNEL_ID" macro
149 */
150/* DMA channel configuration parameters */
151typedef struct {
152 uint32_t srcPeripheralPort; /* Source peripheral port */
153 uint32_t dstPeripheralPort; /* Destination peripheral port */
154 uint32_t srcStatusRegisterAddress; /* Source status register address */
155 uint32_t dstStatusRegisterAddress; /* Destination status register address of type */
156
157 uint32_t srcGatherWidth; /* Number of bytes gathered before successive gather opearation */
158 uint32_t srcGatherJump; /* Number of bytes jumpped before successive gather opearation */
159 uint32_t dstScatterWidth; /* Number of bytes sacattered before successive scatter opearation */
160 uint32_t dstScatterJump; /* Number of bytes jumpped before successive scatter opearation */
161 uint32_t maxDataPerBlock; /* Maximum number of bytes to be transferred per block/descrptor.
162 0 = Maximum possible.
163 */
164
165 dmacHw_ADDRESS_UPDATE_MODE_e srcUpdate; /* Source address update mode */
166 dmacHw_ADDRESS_UPDATE_MODE_e dstUpdate; /* Destination address update mode */
167 dmacHw_TRANSFER_TYPE_e transferType; /* DMA transfer type */
168 dmacHw_TRANSFER_MODE_e transferMode; /* DMA transfer mode */
169 dmacHw_MASTER_INTERFACE_e srcMasterInterface; /* DMA source interface */
170 dmacHw_MASTER_INTERFACE_e dstMasterInterface; /* DMA destination interface */
171 dmacHw_TRANSACTION_WIDTH_e srcMaxTransactionWidth; /* Source transaction width */
172 dmacHw_TRANSACTION_WIDTH_e dstMaxTransactionWidth; /* Destination transaction width */
173 dmacHw_BURST_WIDTH_e srcMaxBurstWidth; /* Source burst width */
174 dmacHw_BURST_WIDTH_e dstMaxBurstWidth; /* Destination burst width */
175 dmacHw_INTERRUPT_e blockTransferInterrupt; /* Block trsnafer interrupt */
176 dmacHw_INTERRUPT_e completeTransferInterrupt; /* Complete DMA trsnafer interrupt */
177 dmacHw_INTERRUPT_e errorInterrupt; /* Error interrupt */
178 dmacHw_CHANNEL_PRIORITY_e channelPriority; /* Channel priority */
179 dmacHw_FLOW_CONTROL_e flowControler; /* Data flow controller */
180} dmacHw_CONFIG_t;
181
182/****************************************************************************/
183/**
184* @brief Initializes DMA
185*
186* This function initializes DMA CSP driver
187*
188* @note
189* Must be called before using any DMA channel
190*/
191/****************************************************************************/
192void dmacHw_initDma(void);
193
194/****************************************************************************/
195/**
196* @brief Exit function for DMA
197*
198* This function isolates DMA from the system
199*
200*/
201/****************************************************************************/
202void dmacHw_exitDma(void);
203
204/****************************************************************************/
205/**
206* @brief Gets a handle to a DMA channel
207*
208* This function returns a handle, representing a control block of a particular DMA channel
209*
210* @return -1 - On Failure
211* handle - On Success, representing a channel control block
212*
213* @note
214* None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
215*/
216/****************************************************************************/
217dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */
218 );
219
220/****************************************************************************/
221/**
222* @brief Initializes a DMA channel for use
223*
224* This function initializes and resets a DMA channel for use
225*
226* @return -1 - On Failure
227* 0 - On Success
228*
229* @note
230* None
231*/
232/****************************************************************************/
233int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
234 );
235
236/****************************************************************************/
237/**
238* @brief Estimates number of descriptor needed to perform certain DMA transfer
239*
240*
241* @return On failure : -1
242* On success : Number of descriptor count
243*
244*
245*/
246/****************************************************************************/
247int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
248 void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
249 void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
250 size_t dataLen /* [ IN ] Data length in bytes */
251 );
252
253/****************************************************************************/
254/**
255* @brief Initializes descriptor ring
256*
257* This function will initializes the descriptor ring of a DMA channel
258*
259*
260* @return -1 - On failure
261* 0 - On success
262* @note
263* - "len" parameter should be obtained from "dmacHw_descriptorLen"
264* - Descriptor buffer MUST be 32 bit aligned and uncached as it
265* is accessed by ARM and DMA
266*/
267/****************************************************************************/
268int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
269 uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
270 uint32_t len, /* [ IN ] Size of the pBuf */
271 uint32_t num /* [ IN ] Number of descriptor in the ring */
272 );
273
274/****************************************************************************/
275/**
276* @brief Finds amount of memory required to form a descriptor ring
277*
278*
279* @return Number of bytes required to form a descriptor ring
280*
281*
282* @note
283* None
284*/
285/****************************************************************************/
286uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */
287 );
288
289/****************************************************************************/
290/**
291* @brief Configure DMA channel
292*
293* @return 0 : On success
294* -1 : On failure
295*/
296/****************************************************************************/
297int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
298 dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */
299 );
300
301/****************************************************************************/
302/**
303* @brief Set descriptors for known data length
304*
305* When DMA has to work as a flow controller, this function prepares the
306* descriptor chain to transfer data
307*
308* from:
309* - Memory to memory
310* - Peripheral to memory
311* - Memory to Peripheral
312* - Peripheral to Peripheral
313*
314* @return -1 - On failure
315* 0 - On success
316*
317*/
318/****************************************************************************/
319int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
320 void *pDescriptor, /* [ IN ] Descriptor buffer */
321 void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
322 void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
323 size_t dataLen /* [ IN ] Length in bytes */
324 );
325
326/****************************************************************************/
327/**
328* @brief Indicates whether DMA transfer is in progress or completed
329*
330* @return DMA transfer status
331* dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing
332* dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed
333* dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error
334*
335*/
336/****************************************************************************/
337dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
338 );
339
340/****************************************************************************/
341/**
342* @brief Set descriptor carrying control information
343*
344* This function will be used to send specific control information to the device
345* using the DMA channel
346*
347*
348* @return -1 - On failure
349* 0 - On success
350*
351* @note
352* None
353*/
354/****************************************************************************/
355int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
356 void *pDescriptor, /* [ IN ] Descriptor buffer */
357 uint32_t ctlAddress, /* [ IN ] Address of the device control register */
358 uint32_t control /* [ IN ] Device control information */
359 );
360
361/****************************************************************************/
362/**
363* @brief Read data DMA transferred to memory
364*
365* This function will read data that has been DMAed to memory while transfering from:
366* - Memory to memory
367* - Peripheral to memory
368*
369* @return 0 - No more data is available to read
370* 1 - More data might be available to read
371*
372*/
373/****************************************************************************/
374int dmacHw_readTransferredData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
375 dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
376 void *pDescriptor, /* [ IN ] Descriptor buffer */
377 void **ppBbuf, /* [ OUT ] Data received */
378 size_t *pLlen /* [ OUT ] Length of the data received */
379 );
380
381/****************************************************************************/
382/**
383* @brief Prepares descriptor ring, when source peripheral working as a flow controller
384*
385* This function will form the descriptor ring by allocating buffers, when source peripheral
386* has to work as a flow controller to transfer data from:
387* - Peripheral to memory.
388*
389* @return -1 - On failure
390* 0 - On success
391*
392*
393* @note
394* None
395*/
396/****************************************************************************/
397int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
398 dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
399 void *pDescriptor, /* [ IN ] Descriptor buffer */
400 uint32_t srcAddr, /* [ IN ] Source peripheral address */
401 void *(*fpAlloc) (int len), /* [ IN ] Function pointer that provides destination memory */
402 int len, /* [ IN ] Number of bytes "fpAlloc" will allocate for destination */
403 int num /* [ IN ] Number of descriptor to set */
404 );
405
406/****************************************************************************/
407/**
408* @brief Program channel register to initiate transfer
409*
410* @return void
411*
412*
413* @note
414* - Descriptor buffer MUST ALWAYS be flushed before calling this function
415* - This function should also be called from ISR to program the channel with
416* pending descriptors
417*/
418/****************************************************************************/
419void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
420 dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
421 void *pDescriptor /* [ IN ] Descriptor buffer */
422 );
423
424/****************************************************************************/
425/**
426* @brief Resets descriptor control information
427*
428* @return void
429*/
430/****************************************************************************/
431void dmacHw_resetDescriptorControl(void *pDescriptor /* [ IN ] Descriptor buffer */
432 );
433
434/****************************************************************************/
435/**
436* @brief Program channel register to stop transfer
437*
438* Ensures the channel is not doing any transfer after calling this function
439*
440* @return void
441*
442*/
443/****************************************************************************/
444void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
445 );
446
447/****************************************************************************/
448/**
449* @brief Check the existance of pending descriptor
450*
451* This function confirmes if there is any pending descriptor in the chain
452* to program the channel
453*
454* @return 1 : Channel need to be programmed with pending descriptor
455* 0 : No more pending descriptor to programe the channel
456*
457* @note
458* - This function should be called from ISR in case there are pending
459* descriptor to program the channel.
460*
461* Example:
462*
463* dmac_isr ()
464* {
465* ...
466* if (dmacHw_descriptorPending (handle))
467* {
468* dmacHw_initiateTransfer (handle);
469* }
470* }
471*
472*/
473/****************************************************************************/
474uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
475 void *pDescriptor /* [ IN ] Descriptor buffer */
476 );
477
478/****************************************************************************/
479/**
480* @brief Deallocates source or destination memory, allocated
481*
482* This function can be called to deallocate data memory that was DMAed successfully
483*
484* @return -1 - On failure
485* 0 - On success
486*
487* @note
488* This function will be called ONLY, when source OR destination address is pointing
489* to dynamic memory
490*/
491/****************************************************************************/
492int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
493 void *pDescriptor, /* [ IN ] Descriptor buffer */
494 void (*fpFree) (void *) /* [ IN ] Function pointer to free data memory */
495 );
496
497/****************************************************************************/
498/**
499* @brief Clears the interrupt
500*
501* This function clears the DMA channel specific interrupt
502*
503* @return N/A
504*
505* @note
506* Must be called under the context of ISR
507*/
508/****************************************************************************/
509void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
510 );
511
512/****************************************************************************/
513/**
514* @brief Returns the cause of channel specific DMA interrupt
515*
516* This function returns the cause of interrupt
517*
518* @return Interrupt status, each bit representing a specific type of interrupt
519* of type dmacHw_INTERRUPT_STATUS_e
520* @note
521* This function should be called under the context of ISR
522*/
523/****************************************************************************/
524dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
525 );
526
527/****************************************************************************/
528/**
529* @brief Indentifies a DMA channel causing interrupt
530*
531* This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e
532*
533* @return NULL : No channel causing DMA interrupt
534* ! NULL : Handle to a channel causing DMA interrupt
535* @note
536* dmacHw_clearInterrupt() must be called with a valid handle after calling this function
537*/
538/****************************************************************************/
539dmacHw_HANDLE_t dmacHw_getInterruptSource(void);
540
541/****************************************************************************/
542/**
543* @brief Sets channel specific user data
544*
545* This function associates user data to a specif DMA channel
546*
547*/
548/****************************************************************************/
549void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
550 void *userData /* [ IN ] User data */
551 );
552
553/****************************************************************************/
554/**
555* @brief Gets channel specific user data
556*
557* This function returns user data specific to a DMA channel
558*
559* @return user data
560*/
561/****************************************************************************/
562void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
563 );
564
565/****************************************************************************/
566/**
567* @brief Displays channel specific registers and other control parameters
568*
569*
570* @return void
571*
572* @note
573* None
574*/
575/****************************************************************************/
576void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
577 void *pDescriptor, /* [ IN ] Descriptor buffer */
578 int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
579 );
580
581/****************************************************************************/
582/**
583* @brief Provides DMA controller attributes
584*
585*
586* @return DMA controller attributes
587*
588* @note
589* None
590*/
591/****************************************************************************/
592uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
593 dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */
594 );
595
596#endif /* _DMACHW_H */
diff --git a/arch/arm/mach-bcmring/include/csp/errno.h b/arch/arm/mach-bcmring/include/csp/errno.h
new file mode 100644
index 000000000000..51357dd5b666
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/errno.h
@@ -0,0 +1,32 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CSP_ERRNO_H
16#define CSP_ERRNO_H
17
18/* ---- Include Files ---------------------------------------------------- */
19
20#if defined(__KERNEL__)
21#include <linux/errno.h>
22#elif defined(CSP_SIMULATION)
23#include <asm-generic/errno.h>
24#else
25#include <errno.h>
26#endif
27
28/* ---- Public Constants and Types --------------------------------------- */
29/* ---- Public Variable Externs ------------------------------------------ */
30/* ---- Public Function Prototypes --------------------------------------- */
31
32#endif /* CSP_ERRNO_H */
diff --git a/arch/arm/mach-bcmring/include/csp/intcHw.h b/arch/arm/mach-bcmring/include/csp/intcHw.h
new file mode 100644
index 000000000000..1c639c8ee08f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/intcHw.h
@@ -0,0 +1,40 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15
16/****************************************************************************/
17/**
18* @file intcHw.h
19*
20* @brief generic interrupt controller API
21*
22* @note
23* None
24*/
25/****************************************************************************/
26
27#ifndef _INTCHW_H
28#define _INTCHW_H
29
30/* ---- Include Files ---------------------------------------------------- */
31#include <mach/csp/intcHw_reg.h>
32
33/* ---- Public Constants and Types --------------------------------------- */
34/* ---- Public Variable Externs ------------------------------------------ */
35/* ---- Public Function Prototypes --------------------------------------- */
36static inline void intcHw_irq_disable(void *basep, uint32_t mask);
37static inline void intcHw_irq_enable(void *basep, uint32_t mask);
38
39#endif /* _INTCHW_H */
40
diff --git a/arch/arm/mach-bcmring/include/csp/module.h b/arch/arm/mach-bcmring/include/csp/module.h
new file mode 100644
index 000000000000..c30d2a5975a6
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/module.h
@@ -0,0 +1,32 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15
16#ifndef CSP_MODULE_H
17#define CSP_MODULE_H
18
19/* ---- Include Files ---------------------------------------------------- */
20
21#ifdef __KERNEL__
22 #include <linux/module.h>
23#else
24 #define EXPORT_SYMBOL(symbol)
25#endif
26
27/* ---- Public Constants and Types --------------------------------------- */
28/* ---- Public Variable Externs ------------------------------------------ */
29/* ---- Public Function Prototypes --------------------------------------- */
30
31
32#endif /* CSP_MODULE_H */
diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h
new file mode 100644
index 000000000000..e5f60bf5a1f3
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/reg.h
@@ -0,0 +1,114 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file reg.h
18*
19* @brief Generic register defintions used in CSP
20*/
21/****************************************************************************/
22
23#ifndef CSP_REG_H
24#define CSP_REG_H
25
26/* ---- Include Files ---------------------------------------------------- */
27
28#include <csp/stdint.h>
29
30/* ---- Public Constants and Types --------------------------------------- */
31
32#define __REG32(x) (*((volatile uint32_t *)(x)))
33#define __REG16(x) (*((volatile uint16_t *)(x)))
34#define __REG8(x) (*((volatile uint8_t *) (x)))
35
36/* Macros used to define a sequence of reserved registers. The start / end */
37/* are byte offsets in the particular register definition, with the "end" */
38/* being the offset of the next un-reserved register. E.g. if offsets */
39/* 0x10 through to 0x1f are reserved, then this reserved area could be */
40/* specified as follows. */
41/* typedef struct */
42/* { */
43/* uint32_t reg1; offset 0x00 */
44/* uint32_t reg2; offset 0x04 */
45/* uint32_t reg3; offset 0x08 */
46/* uint32_t reg4; offset 0x0c */
47/* REG32_RSVD(0x10, 0x20); */
48/* uint32_t reg5; offset 0x20 */
49/* ... */
50/* } EXAMPLE_REG_t; */
51#define REG8_RSVD(start, end) uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)]
52#define REG16_RSVD(start, end) uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)]
53#define REG32_RSVD(start, end) uint32_t rsvd_##start[(end - start) / sizeof(uint32_t)]
54
55/* ---- Public Variable Externs ------------------------------------------ */
56/* ---- Public Function Prototypes --------------------------------------- */
57
58/* Note: When protecting multiple statements, the REG_LOCAL_IRQ_SAVE and */
59/* REG_LOCAL_IRQ_RESTORE must be enclosed in { } to allow the */
60/* flags variable to be declared locally. */
61/* e.g. */
62/* statement1; */
63/* { */
64/* REG_LOCAL_IRQ_SAVE; */
65/* <multiple statements here> */
66/* REG_LOCAL_IRQ_RESTORE; */
67/* } */
68/* statement2; */
69/* */
70
71#if defined(__KERNEL__) && !defined(STANDALONE)
72#include <mach/hardware.h>
73#include <linux/interrupt.h>
74
75#define REG_LOCAL_IRQ_SAVE HW_DECLARE_SPINLOCK(reg32) \
76 unsigned long flags; HW_IRQ_SAVE(reg32, flags)
77
78#define REG_LOCAL_IRQ_RESTORE HW_IRQ_RESTORE(reg32, flags)
79
80#else
81
82#define REG_LOCAL_IRQ_SAVE
83#define REG_LOCAL_IRQ_RESTORE
84
85#endif
86
87static inline void reg32_modify_and(volatile uint32_t *reg, uint32_t value)
88{
89 REG_LOCAL_IRQ_SAVE;
90 *reg &= value;
91 REG_LOCAL_IRQ_RESTORE;
92}
93
94static inline void reg32_modify_or(volatile uint32_t *reg, uint32_t value)
95{
96 REG_LOCAL_IRQ_SAVE;
97 *reg |= value;
98 REG_LOCAL_IRQ_RESTORE;
99}
100
101static inline void reg32_modify_mask(volatile uint32_t *reg, uint32_t mask,
102 uint32_t value)
103{
104 REG_LOCAL_IRQ_SAVE;
105 *reg = (*reg & mask) | value;
106 REG_LOCAL_IRQ_RESTORE;
107}
108
109static inline void reg32_write(volatile uint32_t *reg, uint32_t value)
110{
111 *reg = value;
112}
113
114#endif /* CSP_REG_H */
diff --git a/arch/arm/mach-bcmring/include/csp/secHw.h b/arch/arm/mach-bcmring/include/csp/secHw.h
new file mode 100644
index 000000000000..b9d7e0732dfc
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/secHw.h
@@ -0,0 +1,65 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file secHw.h
18*
19* @brief Definitions for accessing low level security features
20*
21*/
22/****************************************************************************/
23#ifndef SECHW_H
24#define SECHW_H
25
26typedef void (*secHw_FUNC_t) (void);
27
28typedef enum {
29 secHw_MODE_SECURE = 0x0, /* Switches processor into secure mode */
30 secHw_MODE_NONSECURE = 0x1 /* Switches processor into non-secure mode */
31} secHw_MODE;
32
33/****************************************************************************/
34/**
35* @brief Requesting to execute the function in secure mode
36*
37* This function requests the given function to run in secure mode
38*
39*/
40/****************************************************************************/
41void secHw_RunSecure(secHw_FUNC_t /* Function to run in secure mode */
42 );
43
44/****************************************************************************/
45/**
46* @brief Sets the mode
47*
48* his function sets the processor mode (secure/non-secure)
49*
50*/
51/****************************************************************************/
52void secHw_SetMode(secHw_MODE /* Processor mode */
53 );
54
55/****************************************************************************/
56/**
57* @brief Get the current mode
58*
59* This function retieves the processor mode (secure/non-secure)
60*
61*/
62/****************************************************************************/
63void secHw_GetMode(secHw_MODE *);
64
65#endif /* SECHW_H */
diff --git a/arch/arm/mach-bcmring/include/csp/stdint.h b/arch/arm/mach-bcmring/include/csp/stdint.h
new file mode 100644
index 000000000000..3a8718bbf700
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/stdint.h
@@ -0,0 +1,30 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CSP_STDINT_H
16#define CSP_STDINT_H
17
18/* ---- Include Files ---------------------------------------------------- */
19
20#ifdef __KERNEL__
21#include <linux/types.h>
22#else
23#include <stdint.h>
24#endif
25
26/* ---- Public Constants and Types --------------------------------------- */
27/* ---- Public Variable Externs ------------------------------------------ */
28/* ---- Public Function Prototypes --------------------------------------- */
29
30#endif /* CSP_STDINT_H */
diff --git a/arch/arm/mach-bcmring/include/csp/string.h b/arch/arm/mach-bcmring/include/csp/string.h
new file mode 100644
index 000000000000..ad9e4005f141
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/string.h
@@ -0,0 +1,34 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15
16
17#ifndef CSP_STRING_H
18#define CSP_STRING_H
19
20/* ---- Include Files ---------------------------------------------------- */
21
22#ifdef __KERNEL__
23 #include <linux/string.h>
24#else
25 #include <string.h>
26#endif
27
28/* ---- Public Constants and Types --------------------------------------- */
29/* ---- Public Variable Externs ------------------------------------------ */
30/* ---- Public Function Prototypes --------------------------------------- */
31
32
33#endif /* CSP_STRING_H */
34
diff --git a/arch/arm/mach-bcmring/include/csp/tmrHw.h b/arch/arm/mach-bcmring/include/csp/tmrHw.h
new file mode 100644
index 000000000000..f1236d00cb97
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/tmrHw.h
@@ -0,0 +1,263 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file tmrHw.h
18*
19* @brief API definitions for low level Timer driver
20*
21*/
22/****************************************************************************/
23#ifndef _TMRHW_H
24#define _TMRHW_H
25
26#include <csp/stdint.h>
27
28typedef uint32_t tmrHw_ID_t; /* Timer ID */
29typedef uint32_t tmrHw_COUNT_t; /* Timer count */
30typedef uint32_t tmrHw_INTERVAL_t; /* Timer interval */
31typedef uint32_t tmrHw_RATE_t; /* Timer event (count/interrupt) rate */
32
33typedef enum {
34 tmrHw_INTERRUPT_STATUS_SET, /* Interrupted */
35 tmrHw_INTERRUPT_STATUS_UNSET /* No Interrupt */
36} tmrHw_INTERRUPT_STATUS_e;
37
38typedef enum {
39 tmrHw_CAPABILITY_CLOCK, /* Clock speed in HHz */
40 tmrHw_CAPABILITY_RESOLUTION /* Timer resolution in bits */
41} tmrHw_CAPABILITY_e;
42
43/****************************************************************************/
44/**
45* @brief Get timer capability
46*
47* This function returns various capabilities/attributes of a timer
48*
49* @return Numeric capability
50*
51*/
52/****************************************************************************/
53uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
54 tmrHw_CAPABILITY_e capability /* [ IN ] Timer capability */
55);
56
57/****************************************************************************/
58/**
59* @brief Configures a periodic timer in terms of timer interrupt rate
60*
61* This function initializes a periodic timer to generate specific number of
62* timer interrupt per second
63*
64* @return On success: Effective timer frequency
65* On failure: 0
66*
67*/
68/****************************************************************************/
69tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
70 tmrHw_RATE_t rate /* [ IN ] Number of timer interrupt per second */
71);
72
73/****************************************************************************/
74/**
75* @brief Configures a periodic timer to generate timer interrupt after
76* certain time interval
77*
78* This function initializes a periodic timer to generate timer interrupt
79* after every time interval in milisecond
80*
81* @return On success: Effective interval set in mili-second
82* On failure: 0
83*
84*/
85/****************************************************************************/
86tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
87 tmrHw_INTERVAL_t msec /* [ IN ] Interval in mili-second */
88);
89
90/****************************************************************************/
91/**
92* @brief Configures a periodic timer to generate timer interrupt just once
93* after certain time interval
94*
95* This function initializes a periodic timer to generate a single ticks after
96* certain time interval in milisecond
97*
98* @return On success: Effective interval set in mili-second
99* On failure: 0
100*
101*/
102/****************************************************************************/
103tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
104 tmrHw_INTERVAL_t msec /* [ IN ] Interval in mili-second */
105);
106
107/****************************************************************************/
108/**
109* @brief Configures a timer to run as a free running timer
110*
111* This function initializes a timer to run as a free running timer
112*
113* @return Timer resolution (count / sec)
114*
115*/
116/****************************************************************************/
117tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
118 uint32_t divider /* [ IN ] Dividing the clock frequency */
119) __attribute__ ((section(".aramtext")));
120
121/****************************************************************************/
122/**
123* @brief Starts a timer
124*
125* This function starts a preconfigured timer
126*
127* @return -1 - On Failure
128* 0 - On Success
129*/
130/****************************************************************************/
131int tmrHw_startTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
132) __attribute__ ((section(".aramtext")));
133
134/****************************************************************************/
135/**
136* @brief Stops a timer
137*
138* This function stops a running timer
139*
140* @return -1 - On Failure
141* 0 - On Success
142*/
143/****************************************************************************/
144int tmrHw_stopTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
145);
146
147/****************************************************************************/
148/**
149* @brief Gets current timer count
150*
151* This function returns the current timer value
152*
153* @return Current downcounting timer value
154*
155*/
156/****************************************************************************/
157tmrHw_COUNT_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId /* [ IN ] Timer id */
158) __attribute__ ((section(".aramtext")));
159
160/****************************************************************************/
161/**
162* @brief Gets timer count rate
163*
164* This function returns the number of counts per second
165*
166* @return Count rate
167*
168*/
169/****************************************************************************/
170tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId /* [ IN ] Timer id */
171) __attribute__ ((section(".aramtext")));
172
173/****************************************************************************/
174/**
175* @brief Enables timer interrupt
176*
177* This function enables the timer interrupt
178*
179* @return N/A
180*
181*/
182/****************************************************************************/
183void tmrHw_enableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
184);
185
186/****************************************************************************/
187/**
188* @brief Disables timer interrupt
189*
190* This function disable the timer interrupt
191*
192* @return N/A
193*/
194/****************************************************************************/
195void tmrHw_disableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
196);
197
198/****************************************************************************/
199/**
200* @brief Clears the interrupt
201*
202* This function clears the timer interrupt
203*
204* @return N/A
205*
206* @note
207* Must be called under the context of ISR
208*/
209/****************************************************************************/
210void tmrHw_clearInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
211);
212
213/****************************************************************************/
214/**
215* @brief Gets the interrupt status
216*
217* This function returns timer interrupt status
218*
219* @return Interrupt status
220*/
221/****************************************************************************/
222tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId /* [ IN ] Timer id */
223);
224
225/****************************************************************************/
226/**
227* @brief Indentifies a timer causing interrupt
228*
229* This functions returns a timer causing interrupt
230*
231* @return 0xFFFFFFFF : No timer causing an interrupt
232* ! 0xFFFFFFFF : timer causing an interrupt
233* @note
234* tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
235*/
236/****************************************************************************/
237tmrHw_ID_t tmrHw_getInterruptSource(void);
238
239/****************************************************************************/
240/**
241* @brief Displays specific timer registers
242*
243*
244* @return void
245*
246*/
247/****************************************************************************/
248void tmrHw_printDebugInfo(tmrHw_ID_t timerId, /* [ IN ] Timer id */
249 int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
250);
251
252/****************************************************************************/
253/**
254* @brief Use a timer to perform a busy wait delay for a number of usecs.
255*
256* @return N/A
257*/
258/****************************************************************************/
259void tmrHw_udelay(tmrHw_ID_t timerId, /* [ IN ] Timer id */
260 unsigned long usecs /* [ IN ] usec to delay */
261) __attribute__ ((section(".aramtext")));
262
263#endif /* _TMRHW_H */
diff --git a/arch/arm/mach-bcmring/include/mach/clkdev.h b/arch/arm/mach-bcmring/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap.h b/arch/arm/mach-bcmring/include/mach/csp/cap.h
new file mode 100644
index 000000000000..30fa2d540630
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/cap.h
@@ -0,0 +1,63 @@
1/*****************************************************************************
2* Copyright 2009 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CAP_H
16#define CAP_H
17
18/* ---- Include Files ---------------------------------------------------- */
19/* ---- Public Constants and Types --------------------------------------- */
20typedef enum {
21 CAP_NOT_PRESENT = 0,
22 CAP_PRESENT
23} CAP_RC_T;
24
25typedef enum {
26 CAP_VPM,
27 CAP_ETH_PHY,
28 CAP_ETH_GMII,
29 CAP_ETH_SGMII,
30 CAP_USB,
31 CAP_TSC,
32 CAP_EHSS,
33 CAP_SDIO,
34 CAP_UARTB,
35 CAP_KEYPAD,
36 CAP_CLCD,
37 CAP_GE,
38 CAP_LEDM,
39 CAP_BBL,
40 CAP_VDEC,
41 CAP_PIF,
42 CAP_APM,
43 CAP_SPU,
44 CAP_PKA,
45 CAP_RNG,
46} CAP_CAPABILITY_T;
47
48typedef enum {
49 CAP_LCD_WVGA = 0,
50 CAP_LCD_VGA = 0x1,
51 CAP_LCD_WQVGA = 0x2,
52 CAP_LCD_QVGA = 0x3
53} CAP_LCD_RES_T;
54
55/* ---- Public Variable Externs ------------------------------------------ */
56/* ---- Public Function Prototypes --------------------------------------- */
57
58static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index);
59static inline uint32_t cap_getMaxArmSpeedHz(void);
60static inline uint32_t cap_getMaxVpmSpeedHz(void);
61static inline CAP_LCD_RES_T cap_getMaxLcdRes(void);
62
63#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h
new file mode 100644
index 000000000000..933ce68ed90b
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h
@@ -0,0 +1,409 @@
1/*****************************************************************************
2* Copyright 2009 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CAP_INLINE_H
16#define CAP_INLINE_H
17
18/* ---- Include Files ---------------------------------------------------- */
19#include <mach/csp/cap.h>
20#include <cfg_global.h>
21
22/* ---- Public Constants and Types --------------------------------------- */
23#define CAP_CONFIG0_VPM_DIS 0x00000001
24#define CAP_CONFIG0_ETH_PHY0_DIS 0x00000002
25#define CAP_CONFIG0_ETH_PHY1_DIS 0x00000004
26#define CAP_CONFIG0_ETH_GMII0_DIS 0x00000008
27#define CAP_CONFIG0_ETH_GMII1_DIS 0x00000010
28#define CAP_CONFIG0_ETH_SGMII0_DIS 0x00000020
29#define CAP_CONFIG0_ETH_SGMII1_DIS 0x00000040
30#define CAP_CONFIG0_USB0_DIS 0x00000080
31#define CAP_CONFIG0_USB1_DIS 0x00000100
32#define CAP_CONFIG0_TSC_DIS 0x00000200
33#define CAP_CONFIG0_EHSS0_DIS 0x00000400
34#define CAP_CONFIG0_EHSS1_DIS 0x00000800
35#define CAP_CONFIG0_SDIO0_DIS 0x00001000
36#define CAP_CONFIG0_SDIO1_DIS 0x00002000
37#define CAP_CONFIG0_UARTB_DIS 0x00004000
38#define CAP_CONFIG0_KEYPAD_DIS 0x00008000
39#define CAP_CONFIG0_CLCD_DIS 0x00010000
40#define CAP_CONFIG0_GE_DIS 0x00020000
41#define CAP_CONFIG0_LEDM_DIS 0x00040000
42#define CAP_CONFIG0_BBL_DIS 0x00080000
43#define CAP_CONFIG0_VDEC_DIS 0x00100000
44#define CAP_CONFIG0_PIF_DIS 0x00200000
45#define CAP_CONFIG0_RESERVED1_DIS 0x00400000
46#define CAP_CONFIG0_RESERVED2_DIS 0x00800000
47
48#define CAP_CONFIG1_APMA_DIS 0x00000001
49#define CAP_CONFIG1_APMB_DIS 0x00000002
50#define CAP_CONFIG1_APMC_DIS 0x00000004
51#define CAP_CONFIG1_CLCD_RES_MASK 0x00000600
52#define CAP_CONFIG1_CLCD_RES_SHIFT 9
53#define CAP_CONFIG1_CLCD_RES_WVGA (CAP_LCD_WVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
54#define CAP_CONFIG1_CLCD_RES_VGA (CAP_LCD_VGA << CAP_CONFIG1_CLCD_RES_SHIFT)
55#define CAP_CONFIG1_CLCD_RES_WQVGA (CAP_LCD_WQVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
56#define CAP_CONFIG1_CLCD_RES_QVGA (CAP_LCD_QVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
57
58#define CAP_CONFIG2_SPU_DIS 0x00000010
59#define CAP_CONFIG2_PKA_DIS 0x00000020
60#define CAP_CONFIG2_RNG_DIS 0x00000080
61
62#if (CFG_GLOBAL_CHIP == BCM11107)
63#define capConfig0 0
64#define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA
65#define capConfig2 0
66#define CAP_APM_MAX_NUM_CHANS 3
67#elif (CFG_GLOBAL_CHIP == FPGA11107)
68#define capConfig0 0
69#define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA
70#define capConfig2 0
71#define CAP_APM_MAX_NUM_CHANS 3
72#elif (CFG_GLOBAL_CHIP == BCM11109)
73#define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
74#define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA)
75#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
76#define CAP_APM_MAX_NUM_CHANS 2
77#elif (CFG_GLOBAL_CHIP == BCM11170)
78#define capConfig0 (CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_USB0_DIS | CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_CLCD_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
79#define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA)
80#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
81#define CAP_APM_MAX_NUM_CHANS 2
82#elif (CFG_GLOBAL_CHIP == BCM11110)
83#define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
84#define capConfig1 CAP_CONFIG1_APMC_DIS
85#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
86#define CAP_APM_MAX_NUM_CHANS 2
87#elif (CFG_GLOBAL_CHIP == BCM11211)
88#define capConfig0 (CAP_CONFIG0_ETH_PHY0_DIS | CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_ETH_SGMII0_DIS | CAP_CONFIG0_ETH_SGMII1_DIS | CAP_CONFIG0_CLCD_DIS)
89#define capConfig1 CAP_CONFIG1_APMC_DIS
90#define capConfig2 0
91#define CAP_APM_MAX_NUM_CHANS 2
92#else
93#error CFG_GLOBAL_CHIP type capabilities not defined
94#endif
95
96#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107))
97#define CAP_HW_CFG_ARM_CLK_HZ 500000000
98#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
99#define CAP_HW_CFG_ARM_CLK_HZ 300000000
100#elif (CFG_GLOBAL_CHIP == BCM11211)
101#define CAP_HW_CFG_ARM_CLK_HZ 666666666
102#else
103#error CFG_GLOBAL_CHIP type capabilities not defined
104#endif
105
106#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107))
107#define CAP_HW_CFG_VPM_CLK_HZ 333333333
108#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
109#define CAP_HW_CFG_VPM_CLK_HZ 200000000
110#else
111#error CFG_GLOBAL_CHIP type capabilities not defined
112#endif
113
114/* ---- Public Variable Externs ------------------------------------------ */
115/* ---- Public Function Prototypes --------------------------------------- */
116
117/****************************************************************************
118* cap_isPresent -
119*
120* PURPOSE:
121* Determines if the chip has a certain capability present
122*
123* PARAMETERS:
124* capability - type of capability to determine if present
125*
126* RETURNS:
127* CAP_PRESENT or CAP_NOT_PRESENT
128****************************************************************************/
129static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index)
130{
131 CAP_RC_T returnVal = CAP_NOT_PRESENT;
132
133 switch (capability) {
134 case CAP_VPM:
135 {
136 if (!(capConfig0 & CAP_CONFIG0_VPM_DIS)) {
137 returnVal = CAP_PRESENT;
138 }
139 }
140 break;
141
142 case CAP_ETH_PHY:
143 {
144 if ((index == 0)
145 && (!(capConfig0 & CAP_CONFIG0_ETH_PHY0_DIS))) {
146 returnVal = CAP_PRESENT;
147 }
148 if ((index == 1)
149 && (!(capConfig0 & CAP_CONFIG0_ETH_PHY1_DIS))) {
150 returnVal = CAP_PRESENT;
151 }
152 }
153 break;
154
155 case CAP_ETH_GMII:
156 {
157 if ((index == 0)
158 && (!(capConfig0 & CAP_CONFIG0_ETH_GMII0_DIS))) {
159 returnVal = CAP_PRESENT;
160 }
161 if ((index == 1)
162 && (!(capConfig0 & CAP_CONFIG0_ETH_GMII1_DIS))) {
163 returnVal = CAP_PRESENT;
164 }
165 }
166 break;
167
168 case CAP_ETH_SGMII:
169 {
170 if ((index == 0)
171 && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII0_DIS))) {
172 returnVal = CAP_PRESENT;
173 }
174 if ((index == 1)
175 && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII1_DIS))) {
176 returnVal = CAP_PRESENT;
177 }
178 }
179 break;
180
181 case CAP_USB:
182 {
183 if ((index == 0)
184 && (!(capConfig0 & CAP_CONFIG0_USB0_DIS))) {
185 returnVal = CAP_PRESENT;
186 }
187 if ((index == 1)
188 && (!(capConfig0 & CAP_CONFIG0_USB1_DIS))) {
189 returnVal = CAP_PRESENT;
190 }
191 }
192 break;
193
194 case CAP_TSC:
195 {
196 if (!(capConfig0 & CAP_CONFIG0_TSC_DIS)) {
197 returnVal = CAP_PRESENT;
198 }
199 }
200 break;
201
202 case CAP_EHSS:
203 {
204 if ((index == 0)
205 && (!(capConfig0 & CAP_CONFIG0_EHSS0_DIS))) {
206 returnVal = CAP_PRESENT;
207 }
208 if ((index == 1)
209 && (!(capConfig0 & CAP_CONFIG0_EHSS1_DIS))) {
210 returnVal = CAP_PRESENT;
211 }
212 }
213 break;
214
215 case CAP_SDIO:
216 {
217 if ((index == 0)
218 && (!(capConfig0 & CAP_CONFIG0_SDIO0_DIS))) {
219 returnVal = CAP_PRESENT;
220 }
221 if ((index == 1)
222 && (!(capConfig0 & CAP_CONFIG0_SDIO1_DIS))) {
223 returnVal = CAP_PRESENT;
224 }
225 }
226 break;
227
228 case CAP_UARTB:
229 {
230 if (!(capConfig0 & CAP_CONFIG0_UARTB_DIS)) {
231 returnVal = CAP_PRESENT;
232 }
233 }
234 break;
235
236 case CAP_KEYPAD:
237 {
238 if (!(capConfig0 & CAP_CONFIG0_KEYPAD_DIS)) {
239 returnVal = CAP_PRESENT;
240 }
241 }
242 break;
243
244 case CAP_CLCD:
245 {
246 if (!(capConfig0 & CAP_CONFIG0_CLCD_DIS)) {
247 returnVal = CAP_PRESENT;
248 }
249 }
250 break;
251
252 case CAP_GE:
253 {
254 if (!(capConfig0 & CAP_CONFIG0_GE_DIS)) {
255 returnVal = CAP_PRESENT;
256 }
257 }
258 break;
259
260 case CAP_LEDM:
261 {
262 if (!(capConfig0 & CAP_CONFIG0_LEDM_DIS)) {
263 returnVal = CAP_PRESENT;
264 }
265 }
266 break;
267
268 case CAP_BBL:
269 {
270 if (!(capConfig0 & CAP_CONFIG0_BBL_DIS)) {
271 returnVal = CAP_PRESENT;
272 }
273 }
274 break;
275
276 case CAP_VDEC:
277 {
278 if (!(capConfig0 & CAP_CONFIG0_VDEC_DIS)) {
279 returnVal = CAP_PRESENT;
280 }
281 }
282 break;
283
284 case CAP_PIF:
285 {
286 if (!(capConfig0 & CAP_CONFIG0_PIF_DIS)) {
287 returnVal = CAP_PRESENT;
288 }
289 }
290 break;
291
292 case CAP_APM:
293 {
294 if ((index == 0)
295 && (!(capConfig1 & CAP_CONFIG1_APMA_DIS))) {
296 returnVal = CAP_PRESENT;
297 }
298 if ((index == 1)
299 && (!(capConfig1 & CAP_CONFIG1_APMB_DIS))) {
300 returnVal = CAP_PRESENT;
301 }
302 if ((index == 2)
303 && (!(capConfig1 & CAP_CONFIG1_APMC_DIS))) {
304 returnVal = CAP_PRESENT;
305 }
306 }
307 break;
308
309 case CAP_SPU:
310 {
311 if (!(capConfig2 & CAP_CONFIG2_SPU_DIS)) {
312 returnVal = CAP_PRESENT;
313 }
314 }
315 break;
316
317 case CAP_PKA:
318 {
319 if (!(capConfig2 & CAP_CONFIG2_PKA_DIS)) {
320 returnVal = CAP_PRESENT;
321 }
322 }
323 break;
324
325 case CAP_RNG:
326 {
327 if (!(capConfig2 & CAP_CONFIG2_RNG_DIS)) {
328 returnVal = CAP_PRESENT;
329 }
330 }
331 break;
332
333 default:
334 {
335 }
336 break;
337 }
338 return returnVal;
339}
340
341/****************************************************************************
342* cap_getMaxArmSpeedHz -
343*
344* PURPOSE:
345* Determines the maximum speed of the ARM CPU
346*
347* PARAMETERS:
348* none
349*
350* RETURNS:
351* clock speed in Hz that the ARM processor is able to run at
352****************************************************************************/
353static inline uint32_t cap_getMaxArmSpeedHz(void)
354{
355#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107))
356 return 500000000;
357#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
358 return 300000000;
359#elif (CFG_GLOBAL_CHIP == BCM11211)
360 return 666666666;
361#else
362#error CFG_GLOBAL_CHIP type capabilities not defined
363#endif
364}
365
366/****************************************************************************
367* cap_getMaxVpmSpeedHz -
368*
369* PURPOSE:
370* Determines the maximum speed of the VPM
371*
372* PARAMETERS:
373* none
374*
375* RETURNS:
376* clock speed in Hz that the VPM is able to run at
377****************************************************************************/
378static inline uint32_t cap_getMaxVpmSpeedHz(void)
379{
380#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107))
381 return 333333333;
382#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
383 return 200000000;
384#else
385#error CFG_GLOBAL_CHIP type capabilities not defined
386#endif
387}
388
389/****************************************************************************
390* cap_getMaxLcdRes -
391*
392* PURPOSE:
393* Determines the maximum LCD resolution capabilities
394*
395* PARAMETERS:
396* none
397*
398* RETURNS:
399* CAP_LCD_WVGA, CAP_LCD_VGA, CAP_LCD_WQVGA or CAP_LCD_QVGA
400*
401****************************************************************************/
402static inline CAP_LCD_RES_T cap_getMaxLcdRes(void)
403{
404 return (CAP_LCD_RES_T)
405 ((capConfig1 & CAP_CONFIG1_CLCD_RES_MASK) >>
406 CAP_CONFIG1_CLCD_RES_SHIFT);
407}
408
409#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
new file mode 100644
index 000000000000..70eaea866cfe
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
@@ -0,0 +1,1123 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CHIPC_DEF_H
16#define CHIPC_DEF_H
17
18/* ---- Include Files ----------------------------------------------------- */
19
20#include <csp/stdint.h>
21#include <csp/errno.h>
22#include <csp/reg.h>
23#include <mach/csp/chipcHw_reg.h>
24
25/* ---- Public Constants and Types ---------------------------------------- */
26
27/* Set 1 to configure DDR/VPM phase alignment by HW */
28#define chipcHw_DDR_HW_PHASE_ALIGN 0
29#define chipcHw_VPM_HW_PHASE_ALIGN 0
30
31typedef uint32_t chipcHw_freq;
32
33/* Configurable miscellaneous clocks */
34typedef enum {
35 chipcHw_CLOCK_DDR, /* DDR PHY Clock */
36 chipcHw_CLOCK_ARM, /* ARM Clock */
37 chipcHw_CLOCK_ESW, /* Ethernet Switch Clock */
38 chipcHw_CLOCK_VPM, /* VPM Clock */
39 chipcHw_CLOCK_ESW125, /* Ethernet MII Clock */
40 chipcHw_CLOCK_UART, /* UART Clock */
41 chipcHw_CLOCK_SDIO0, /* SDIO 0 Clock */
42 chipcHw_CLOCK_SDIO1, /* SDIO 1 Clock */
43 chipcHw_CLOCK_SPI, /* SPI Clock */
44 chipcHw_CLOCK_ETM, /* ARM ETM Clock */
45
46 chipcHw_CLOCK_BUS, /* BUS Clock */
47 chipcHw_CLOCK_OTP, /* OTP Clock */
48 chipcHw_CLOCK_I2C, /* I2C Host Clock */
49 chipcHw_CLOCK_I2S0, /* I2S 0 Host Clock */
50 chipcHw_CLOCK_RTBUS, /* DDR PHY Configuration Clock */
51 chipcHw_CLOCK_APM100, /* APM100 Clock */
52 chipcHw_CLOCK_TSC, /* Touch screen Clock */
53 chipcHw_CLOCK_LED, /* LED Clock */
54
55 chipcHw_CLOCK_USB, /* USB Clock */
56 chipcHw_CLOCK_LCD, /* LCD CLock */
57 chipcHw_CLOCK_APM, /* APM Clock */
58
59 chipcHw_CLOCK_I2S1, /* I2S 1 Host Clock */
60} chipcHw_CLOCK_e;
61
62/* System booting strap options */
63typedef enum {
64 chipcHw_BOOT_DEVICE_UART = chipcHw_STRAPS_BOOT_DEVICE_UART,
65 chipcHw_BOOT_DEVICE_SERIAL_FLASH =
66 chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH,
67 chipcHw_BOOT_DEVICE_NOR_FLASH_16 =
68 chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16,
69 chipcHw_BOOT_DEVICE_NAND_FLASH_8 =
70 chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8,
71 chipcHw_BOOT_DEVICE_NAND_FLASH_16 =
72 chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16
73} chipcHw_BOOT_DEVICE_e;
74
75/* System booting modes */
76typedef enum {
77 chipcHw_BOOT_MODE_NORMAL = chipcHw_STRAPS_BOOT_MODE_NORMAL,
78 chipcHw_BOOT_MODE_DBG_SW = chipcHw_STRAPS_BOOT_MODE_DBG_SW,
79 chipcHw_BOOT_MODE_DBG_BOOT = chipcHw_STRAPS_BOOT_MODE_DBG_BOOT,
80 chipcHw_BOOT_MODE_NORMAL_QUIET = chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET
81} chipcHw_BOOT_MODE_e;
82
83/* NAND Flash page size strap options */
84typedef enum {
85 chipcHw_NAND_PAGESIZE_512 = chipcHw_STRAPS_NAND_PAGESIZE_512,
86 chipcHw_NAND_PAGESIZE_2048 = chipcHw_STRAPS_NAND_PAGESIZE_2048,
87 chipcHw_NAND_PAGESIZE_4096 = chipcHw_STRAPS_NAND_PAGESIZE_4096,
88 chipcHw_NAND_PAGESIZE_EXT = chipcHw_STRAPS_NAND_PAGESIZE_EXT
89} chipcHw_NAND_PAGESIZE_e;
90
91/* GPIO Pin function */
92typedef enum {
93 chipcHw_GPIO_FUNCTION_KEYPAD = chipcHw_REG_GPIO_MUX_KEYPAD,
94 chipcHw_GPIO_FUNCTION_I2CH = chipcHw_REG_GPIO_MUX_I2CH,
95 chipcHw_GPIO_FUNCTION_SPI = chipcHw_REG_GPIO_MUX_SPI,
96 chipcHw_GPIO_FUNCTION_UART = chipcHw_REG_GPIO_MUX_UART,
97 chipcHw_GPIO_FUNCTION_LEDMTXP = chipcHw_REG_GPIO_MUX_LEDMTXP,
98 chipcHw_GPIO_FUNCTION_LEDMTXS = chipcHw_REG_GPIO_MUX_LEDMTXS,
99 chipcHw_GPIO_FUNCTION_SDIO0 = chipcHw_REG_GPIO_MUX_SDIO0,
100 chipcHw_GPIO_FUNCTION_SDIO1 = chipcHw_REG_GPIO_MUX_SDIO1,
101 chipcHw_GPIO_FUNCTION_PCM = chipcHw_REG_GPIO_MUX_PCM,
102 chipcHw_GPIO_FUNCTION_I2S = chipcHw_REG_GPIO_MUX_I2S,
103 chipcHw_GPIO_FUNCTION_ETM = chipcHw_REG_GPIO_MUX_ETM,
104 chipcHw_GPIO_FUNCTION_DEBUG = chipcHw_REG_GPIO_MUX_DEBUG,
105 chipcHw_GPIO_FUNCTION_MISC = chipcHw_REG_GPIO_MUX_MISC,
106 chipcHw_GPIO_FUNCTION_GPIO = chipcHw_REG_GPIO_MUX_GPIO
107} chipcHw_GPIO_FUNCTION_e;
108
109/* PIN Output slew rate */
110typedef enum {
111 chipcHw_PIN_SLEW_RATE_HIGH = chipcHw_REG_SLEW_RATE_HIGH,
112 chipcHw_PIN_SLEW_RATE_NORMAL = chipcHw_REG_SLEW_RATE_NORMAL
113} chipcHw_PIN_SLEW_RATE_e;
114
115/* PIN Current drive strength */
116typedef enum {
117 chipcHw_PIN_CURRENT_STRENGTH_2mA = chipcHw_REG_CURRENT_STRENGTH_2mA,
118 chipcHw_PIN_CURRENT_STRENGTH_4mA = chipcHw_REG_CURRENT_STRENGTH_4mA,
119 chipcHw_PIN_CURRENT_STRENGTH_6mA = chipcHw_REG_CURRENT_STRENGTH_6mA,
120 chipcHw_PIN_CURRENT_STRENGTH_8mA = chipcHw_REG_CURRENT_STRENGTH_8mA,
121 chipcHw_PIN_CURRENT_STRENGTH_10mA = chipcHw_REG_CURRENT_STRENGTH_10mA,
122 chipcHw_PIN_CURRENT_STRENGTH_12mA = chipcHw_REG_CURRENT_STRENGTH_12mA
123} chipcHw_PIN_CURRENT_STRENGTH_e;
124
125/* PIN Pull up register settings */
126typedef enum {
127 chipcHw_PIN_PULL_NONE = chipcHw_REG_PULL_NONE,
128 chipcHw_PIN_PULL_UP = chipcHw_REG_PULL_UP,
129 chipcHw_PIN_PULL_DOWN = chipcHw_REG_PULL_DOWN
130} chipcHw_PIN_PULL_e;
131
132/* PIN input type settings */
133typedef enum {
134 chipcHw_PIN_INPUTTYPE_CMOS = chipcHw_REG_INPUTTYPE_CMOS,
135 chipcHw_PIN_INPUTTYPE_ST = chipcHw_REG_INPUTTYPE_ST
136} chipcHw_PIN_INPUTTYPE_e;
137
138/* Allow/Disalow the support of spread spectrum */
139typedef enum {
140 chipcHw_SPREAD_SPECTRUM_DISALLOW, /* Spread spectrum support is not allowed */
141 chipcHw_SPREAD_SPECTRUM_ALLOW /* Spread spectrum support is allowed */
142} chipcHw_SPREAD_SPECTRUM_e;
143
144typedef struct {
145 chipcHw_SPREAD_SPECTRUM_e ssSupport; /* Allow/Disalow to support spread spectrum.
146 If supported, call chipcHw_enableSpreadSpectrum ()
147 to activate the spread spectrum with desired spread. */
148 uint32_t pllVcoFreqHz; /* PLL VCO frequency in Hz */
149 uint32_t pll2VcoFreqHz; /* PLL2 VCO frequency in Hz */
150 uint32_t busClockFreqHz; /* Bus clock frequency in Hz */
151 uint32_t armBusRatio; /* ARM clock : Bus clock */
152 uint32_t vpmBusRatio; /* VPM clock : Bus clock */
153 uint32_t ddrBusRatio; /* DDR clock : Bus clock */
154} chipcHw_INIT_PARAM_t;
155
156/* CHIP revision number */
157typedef enum {
158 chipcHw_REV_NUMBER_A0 = chipcHw_REG_REV_A0,
159 chipcHw_REV_NUMBER_B0 = chipcHw_REG_REV_B0
160} chipcHw_REV_NUMBER_e;
161
162typedef enum {
163 chipcHw_VPM_HW_PHASE_INTR_DISABLE = chipcHw_REG_VPM_INTR_DISABLE,
164 chipcHw_VPM_HW_PHASE_INTR_FAST = chipcHw_REG_VPM_INTR_FAST,
165 chipcHw_VPM_HW_PHASE_INTR_MEDIUM = chipcHw_REG_VPM_INTR_MEDIUM,
166 chipcHw_VPM_HW_PHASE_INTR_SLOW = chipcHw_REG_VPM_INTR_SLOW
167} chipcHw_VPM_HW_PHASE_INTR_e;
168
169typedef enum {
170 chipcHw_DDR_HW_PHASE_MARGIN_STRICT, /* Strict margin for DDR phase align condition */
171 chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM, /* Medium margin for DDR phase align condition */
172 chipcHw_DDR_HW_PHASE_MARGIN_WIDE /* Wider margin for DDR phase align condition */
173} chipcHw_DDR_HW_PHASE_MARGIN_e;
174
175typedef enum {
176 chipcHw_VPM_HW_PHASE_MARGIN_STRICT, /* Strict margin for VPM phase align condition */
177 chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM, /* Medium margin for VPM phase align condition */
178 chipcHw_VPM_HW_PHASE_MARGIN_WIDE /* Wider margin for VPM phase align condition */
179} chipcHw_VPM_HW_PHASE_MARGIN_e;
180
181#define chipcHw_XTAL_FREQ_Hz 25000000 /* Reference clock frequency in Hz */
182
183/* Programable pin defines */
184#define chipcHw_PIN_GPIO(n) ((((n) >= 0) && ((n) < (chipcHw_GPIO_COUNT))) ? (n) : 0xFFFFFFFF)
185 /* GPIO pin 0 - 60 */
186#define chipcHw_PIN_UARTTXD (chipcHw_GPIO_COUNT + 0) /* UART Transmit */
187#define chipcHw_PIN_NVI_A (chipcHw_GPIO_COUNT + 1) /* NVI Interface */
188#define chipcHw_PIN_NVI_D (chipcHw_GPIO_COUNT + 2) /* NVI Interface */
189#define chipcHw_PIN_NVI_OEB (chipcHw_GPIO_COUNT + 3) /* NVI Interface */
190#define chipcHw_PIN_NVI_WEB (chipcHw_GPIO_COUNT + 4) /* NVI Interface */
191#define chipcHw_PIN_NVI_CS (chipcHw_GPIO_COUNT + 5) /* NVI Interface */
192#define chipcHw_PIN_NVI_NAND_CSB (chipcHw_GPIO_COUNT + 6) /* NVI Interface */
193#define chipcHw_PIN_NVI_FLASHWP (chipcHw_GPIO_COUNT + 7) /* NVI Interface */
194#define chipcHw_PIN_NVI_NAND_RDYB (chipcHw_GPIO_COUNT + 8) /* NVI Interface */
195#define chipcHw_PIN_CL_DATA_0_17 (chipcHw_GPIO_COUNT + 9) /* LCD Data 0 - 17 */
196#define chipcHw_PIN_CL_DATA_18_20 (chipcHw_GPIO_COUNT + 10) /* LCD Data 18 - 20 */
197#define chipcHw_PIN_CL_DATA_21_23 (chipcHw_GPIO_COUNT + 11) /* LCD Data 21 - 23 */
198#define chipcHw_PIN_CL_POWER (chipcHw_GPIO_COUNT + 12) /* LCD Power */
199#define chipcHw_PIN_CL_ACK (chipcHw_GPIO_COUNT + 13) /* LCD Ack */
200#define chipcHw_PIN_CL_FP (chipcHw_GPIO_COUNT + 14) /* LCD FP */
201#define chipcHw_PIN_CL_LP (chipcHw_GPIO_COUNT + 15) /* LCD LP */
202#define chipcHw_PIN_UARTRXD (chipcHw_GPIO_COUNT + 16) /* UART Receive */
203
204/* ---- Public Variable Externs ------------------------------------------ */
205/* ---- Public Function Prototypes --------------------------------------- */
206
207/****************************************************************************/
208/**
209* @brief Initializes the clock module
210*
211*/
212/****************************************************************************/
213void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */
214 ) __attribute__ ((section(".aramtext")));
215
216/****************************************************************************/
217/**
218* @brief Enables the PLL1
219*
220* This function enables the PLL1
221*
222*/
223/****************************************************************************/
224void chipcHw_pll1Enable(uint32_t vcoFreqHz, /* [ IN ] VCO frequency in Hz */
225 chipcHw_SPREAD_SPECTRUM_e ssSupport /* [ IN ] SS status */
226 ) __attribute__ ((section(".aramtext")));
227
228/****************************************************************************/
229/**
230* @brief Enables the PLL2
231*
232* This function enables the PLL2
233*
234*/
235/****************************************************************************/
236void chipcHw_pll2Enable(uint32_t vcoFreqHz /* [ IN ] VCO frequency in Hz */
237 ) __attribute__ ((section(".aramtext")));
238
239/****************************************************************************/
240/**
241* @brief Disable the PLL1
242*
243*/
244/****************************************************************************/
245static inline void chipcHw_pll1Disable(void);
246
247/****************************************************************************/
248/**
249* @brief Disable the PLL2
250*
251*/
252/****************************************************************************/
253static inline void chipcHw_pll2Disable(void);
254
255/****************************************************************************/
256/**
257* @brief Set clock fequency for miscellaneous configurable clocks
258*
259* This function sets clock frequency
260*
261* @return Configured clock frequency in KHz
262*
263*/
264/****************************************************************************/
265chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
266 ) __attribute__ ((section(".aramtext")));
267
268/****************************************************************************/
269/**
270* @brief Set clock fequency for miscellaneous configurable clocks
271*
272* This function sets clock frequency
273*
274* @return Configured clock frequency in Hz
275*
276*/
277/****************************************************************************/
278chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */
279 uint32_t freq /* [ IN ] Clock frequency in Hz */
280 ) __attribute__ ((section(".aramtext")));
281
282/****************************************************************************/
283/**
284* @brief Set VPM clock in sync with BUS clock
285*
286* This function does the phase adjustment between VPM and BUS clock
287*
288* @return >= 0 : On success ( # of adjustment required )
289* -1 : On failure
290*/
291/****************************************************************************/
292int chipcHw_vpmPhaseAlign(void);
293
294/****************************************************************************/
295/**
296* @brief Enables core a clock of a certain device
297*
298* This function enables a core clock
299*
300* @return void
301*
302* @note Doesnot affect the bus interface clock
303*/
304/****************************************************************************/
305static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
306 );
307
308/****************************************************************************/
309/**
310* @brief Disabled a core clock of a certain device
311*
312* This function disables a core clock
313*
314* @return void
315*
316* @note Doesnot affect the bus interface clock
317*/
318/****************************************************************************/
319static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
320 );
321
322/****************************************************************************/
323/**
324* @brief Enables bypass clock of a certain device
325*
326* This function enables bypass clock
327*
328* @note Doesnot affect the bus interface clock
329*/
330/****************************************************************************/
331static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
332 );
333
334/****************************************************************************/
335/**
336* @brief Disabled bypass clock of a certain device
337*
338* This function disables bypass clock
339*
340* @note Doesnot affect the bus interface clock
341*/
342/****************************************************************************/
343static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
344 );
345
346/****************************************************************************/
347/**
348* @brief Get Numeric Chip ID
349*
350* This function returns Chip ID that includes the revison number
351*
352* @return Complete numeric Chip ID
353*
354*/
355/****************************************************************************/
356static inline uint32_t chipcHw_getChipId(void);
357
358/****************************************************************************/
359/**
360* @brief Get Chip Product ID
361*
362* This function returns Chip Product ID
363*
364* @return Chip Product ID
365*/
366/****************************************************************************/
367static inline uint32_t chipcHw_getChipProductId(void);
368
369/****************************************************************************/
370/**
371* @brief Get revision number
372*
373* This function returns revision number of the chip
374*
375* @return Revision number
376*/
377/****************************************************************************/
378static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void);
379
380/****************************************************************************/
381/**
382* @brief Enables bus interface clock
383*
384* Enables bus interface clock of various device
385*
386* @return void
387*
388* @note use chipcHw_REG_BUS_CLOCK_XXXX
389*/
390/****************************************************************************/
391static inline void chipcHw_busInterfaceClockEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_BUS_CLOCK_XXXXX */
392 );
393
394/****************************************************************************/
395/**
396* @brief Disables bus interface clock
397*
398* Disables bus interface clock of various device
399*
400* @return void
401*
402* @note use chipcHw_REG_BUS_CLOCK_XXXX
403*/
404/****************************************************************************/
405static inline void chipcHw_busInterfaceClockDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_BUS_CLOCK_XXXXX */
406 );
407
408/****************************************************************************/
409/**
410* @brief Enables various audio channels
411*
412* Enables audio channel
413*
414* @return void
415*
416* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
417*/
418/****************************************************************************/
419static inline void chipcHw_audioChannelEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_AUDIO_CHANNEL_XXXXXX */
420 );
421
422/****************************************************************************/
423/**
424* @brief Disables various audio channels
425*
426* Disables audio channel
427*
428* @return void
429*
430* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
431*/
432/****************************************************************************/
433static inline void chipcHw_audioChannelDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_AUDIO_CHANNEL_XXXXXX */
434 );
435
436/****************************************************************************/
437/**
438* @brief Soft resets devices
439*
440* Soft resets various devices
441*
442* @return void
443*
444* @note use chipcHw_REG_SOFT_RESET_XXXXXX defines
445*/
446/****************************************************************************/
447static inline void chipcHw_softReset(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
448 );
449
450static inline void chipcHw_softResetDisable(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
451 );
452
453static inline void chipcHw_softResetEnable(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
454 );
455
456/****************************************************************************/
457/**
458* @brief Configures misc CHIP functionality
459*
460* Configures CHIP functionality
461*
462* @return void
463*
464* @note use chipcHw_REG_MISC_CTRL_XXXXXX
465*/
466/****************************************************************************/
467static inline void chipcHw_miscControl(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
468 );
469
470static inline void chipcHw_miscControlDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
471 );
472
473static inline void chipcHw_miscControlEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
474 );
475
476/****************************************************************************/
477/**
478* @brief Set OTP options
479*
480* Set OTP options
481*
482* @return void
483*
484* @note use chipcHw_REG_OTP_XXXXXX
485*/
486/****************************************************************************/
487static inline void chipcHw_setOTPOption(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_OTP_XXXXXX */
488 );
489
490/****************************************************************************/
491/**
492* @brief Get sticky bits
493*
494* @return Sticky bit options of type chipcHw_REG_STICKY_XXXXXX
495*
496*/
497/****************************************************************************/
498static inline uint32_t chipcHw_getStickyBits(void);
499
500/****************************************************************************/
501/**
502* @brief Set sticky bits
503*
504* @return void
505*
506* @note use chipcHw_REG_STICKY_XXXXXX
507*/
508/****************************************************************************/
509static inline void chipcHw_setStickyBits(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */
510 );
511
512/****************************************************************************/
513/**
514* @brief Clear sticky bits
515*
516* @return void
517*
518* @note use chipcHw_REG_STICKY_XXXXXX
519*/
520/****************************************************************************/
521static inline void chipcHw_clearStickyBits(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */
522 );
523
524/****************************************************************************/
525/**
526* @brief Get software override strap options
527*
528* Retrieves software override strap options
529*
530* @return Software override strap value
531*
532*/
533/****************************************************************************/
534static inline uint32_t chipcHw_getSoftStraps(void);
535
536/****************************************************************************/
537/**
538* @brief Set software override strap options
539*
540* set software override strap options
541*
542* @return nothing
543*
544*/
545/****************************************************************************/
546static inline void chipcHw_setSoftStraps(uint32_t strapOptions);
547
548/****************************************************************************/
549/**
550* @brief Get pin strap options
551*
552* Retrieves pin strap options
553*
554* @return Pin strap value
555*
556*/
557/****************************************************************************/
558static inline uint32_t chipcHw_getPinStraps(void);
559
560/****************************************************************************/
561/**
562* @brief Get valid pin strap options
563*
564* Retrieves valid pin strap options
565*
566* @return valid Pin strap value
567*
568*/
569/****************************************************************************/
570static inline uint32_t chipcHw_getValidStraps(void);
571
572/****************************************************************************/
573/**
574* @brief Initialize valid pin strap options
575*
576* Retrieves valid pin strap options by copying HW strap options to soft register
577* (if chipcHw_STRAPS_SOFT_OVERRIDE not set)
578*
579* @return nothing
580*
581*/
582/****************************************************************************/
583static inline void chipcHw_initValidStraps(void);
584
585/****************************************************************************/
586/**
587* @brief Get status (enabled/disabled) of bus interface clock
588*
589* This function returns the status of devices' bus interface clock
590*
591* @return Bus interface clock
592*
593*/
594/****************************************************************************/
595static inline uint32_t chipcHw_getBusInterfaceClockStatus(void);
596
597/****************************************************************************/
598/**
599* @brief Get boot device
600*
601* This function returns the device type used in booting the system
602*
603* @return Boot device of type chipcHw_BOOT_DEVICE_e
604*
605*/
606/****************************************************************************/
607static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void);
608
609/****************************************************************************/
610/**
611* @brief Get boot mode
612*
613* This function returns the way the system was booted
614*
615* @return Boot mode of type chipcHw_BOOT_MODE_e
616*
617*/
618/****************************************************************************/
619static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void);
620
621/****************************************************************************/
622/**
623* @brief Get NAND flash page size
624*
625* This function returns the NAND device page size
626*
627* @return Boot NAND device page size
628*
629*/
630/****************************************************************************/
631static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void);
632
633/****************************************************************************/
634/**
635* @brief Get NAND flash address cycle configuration
636*
637* This function returns the NAND flash address cycle configuration
638*
639* @return 0 = Do not extra address cycle, 1 = Add extra cycle
640*
641*/
642/****************************************************************************/
643static inline int chipcHw_getNandExtraCycle(void);
644
645/****************************************************************************/
646/**
647* @brief Activates PIF interface
648*
649* This function activates PIF interface by taking control of LCD pins
650*
651* @note
652* When activated, LCD pins will be defined as follows for PIF operation
653*
654* CLD[17:0] = pif_data[17:0]
655* CLD[23:18] = pif_address[5:0]
656* CLPOWER = pif_wr_str
657* CLCP = pif_rd_str
658* CLAC = pif_hat1
659* CLFP = pif_hrdy1
660* CLLP = pif_hat2
661* GPIO[42] = pif_hrdy2
662*
663* In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin
664*
665*/
666/****************************************************************************/
667static inline void chipcHw_activatePifInterface(void);
668
669/****************************************************************************/
670/**
671* @brief Activates LCD interface
672*
673* This function activates LCD interface
674*
675* @note
676* When activated, LCD pins will be defined as follows
677*
678* CLD[17:0] = LCD data
679* CLD[23:18] = LCD data
680* CLPOWER = LCD power
681* CLCP =
682* CLAC = LCD ack
683* CLFP =
684* CLLP =
685*/
686/****************************************************************************/
687static inline void chipcHw_activateLcdInterface(void);
688
689/****************************************************************************/
690/**
691* @brief Deactivates PIF/LCD interface
692*
693* This function deactivates PIF/LCD interface
694*
695* @note
696* When deactivated LCD pins will be in rti-stated
697*
698*/
699/****************************************************************************/
700static inline void chipcHw_deactivatePifLcdInterface(void);
701
702/****************************************************************************/
703/**
704* @brief Get to know the configuration of GPIO pin
705*
706*/
707/****************************************************************************/
708static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin /* GPIO Pin number */
709 );
710
711/****************************************************************************/
712/**
713* @brief Configure GPIO pin function
714*
715*/
716/****************************************************************************/
717static inline void chipcHw_setGpioPinFunction(int pin, /* GPIO Pin number */
718 chipcHw_GPIO_FUNCTION_e func /* Configuration function */
719 );
720
721/****************************************************************************/
722/**
723* @brief Set Pin slew rate
724*
725* This function sets the slew of individual pin
726*
727*/
728/****************************************************************************/
729static inline void chipcHw_setPinSlewRate(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
730 chipcHw_PIN_SLEW_RATE_e slewRate /* Pin slew rate */
731 );
732
733/****************************************************************************/
734/**
735* @brief Set Pin output drive current
736*
737* This function sets output drive current of individual pin
738*
739* Note: Avoid the use of the word 'current' since linux headers define this
740* to be the current task.
741*/
742/****************************************************************************/
743static inline void chipcHw_setPinOutputCurrent(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
744 chipcHw_PIN_CURRENT_STRENGTH_e curr /* Pin current rating */
745 );
746
747/****************************************************************************/
748/**
749* @brief Set Pin pullup register
750*
751* This function sets pullup register of individual pin
752*
753*/
754/****************************************************************************/
755static inline void chipcHw_setPinPullup(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
756 chipcHw_PIN_PULL_e pullup /* Pullup register settings */
757 );
758
759/****************************************************************************/
760/**
761* @brief Set Pin input type
762*
763* This function sets input type of individual Pin
764*
765*/
766/****************************************************************************/
767static inline void chipcHw_setPinInputType(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
768 chipcHw_PIN_INPUTTYPE_e inputType /* Pin input type */
769 );
770
771/****************************************************************************/
772/**
773* @brief Retrieves a string representation of the mux setting for a pin.
774*
775* @return Pointer to a character string.
776*/
777/****************************************************************************/
778
779const char *chipcHw_getGpioPinFunctionStr(int pin);
780
781/****************************************************************************/
782/** @brief issue warmReset
783 */
784/****************************************************************************/
785void chipcHw_reset(uint32_t mask);
786
787/****************************************************************************/
788/** @brief clock reconfigure
789 */
790/****************************************************************************/
791void chipcHw_clockReconfig(uint32_t busHz, uint32_t armRatio, uint32_t vpmRatio,
792 uint32_t ddrRatio);
793
794/****************************************************************************/
795/**
796* @brief Enable Spread Spectrum
797*
798* @note chipcHw_Init() must be called earlier
799*/
800/****************************************************************************/
801static inline void chipcHw_enableSpreadSpectrum(void);
802
803/****************************************************************************/
804/**
805* @brief Disable Spread Spectrum
806*
807*/
808/****************************************************************************/
809static inline void chipcHw_disableSpreadSpectrum(void);
810
811/****************************************************************************/
812/** @brief Checks if software strap is enabled
813 *
814 * @return 1 : When enable
815 * 0 : When disable
816 */
817/****************************************************************************/
818static inline int chipcHw_isSoftwareStrapsEnable(void);
819
820/****************************************************************************/
821/** @brief Enable software strap
822 */
823/****************************************************************************/
824static inline void chipcHw_softwareStrapsEnable(void);
825
826/****************************************************************************/
827/** @brief Disable software strap
828 */
829/****************************************************************************/
830static inline void chipcHw_softwareStrapsDisable(void);
831
832/****************************************************************************/
833/** @brief PLL test enable
834 */
835/****************************************************************************/
836static inline void chipcHw_pllTestEnable(void);
837
838/****************************************************************************/
839/** @brief PLL2 test enable
840 */
841/****************************************************************************/
842static inline void chipcHw_pll2TestEnable(void);
843
844/****************************************************************************/
845/** @brief PLL test disable
846 */
847/****************************************************************************/
848static inline void chipcHw_pllTestDisable(void);
849
850/****************************************************************************/
851/** @brief PLL2 test disable
852 */
853/****************************************************************************/
854static inline void chipcHw_pll2TestDisable(void);
855
856/****************************************************************************/
857/** @brief Get PLL test status
858 */
859/****************************************************************************/
860static inline int chipcHw_isPllTestEnable(void);
861
862/****************************************************************************/
863/** @brief Get PLL2 test status
864 */
865/****************************************************************************/
866static inline int chipcHw_isPll2TestEnable(void);
867
868/****************************************************************************/
869/** @brief PLL test select
870 */
871/****************************************************************************/
872static inline void chipcHw_pllTestSelect(uint32_t val);
873
874/****************************************************************************/
875/** @brief PLL2 test select
876 */
877/****************************************************************************/
878static inline void chipcHw_pll2TestSelect(uint32_t val);
879
880/****************************************************************************/
881/** @brief Get PLL test selected option
882 */
883/****************************************************************************/
884static inline uint8_t chipcHw_getPllTestSelected(void);
885
886/****************************************************************************/
887/** @brief Get PLL2 test selected option
888 */
889/****************************************************************************/
890static inline uint8_t chipcHw_getPll2TestSelected(void);
891
892/****************************************************************************/
893/**
894* @brief Enables DDR SW phase alignment interrupt
895*/
896/****************************************************************************/
897static inline void chipcHw_ddrPhaseAlignInterruptEnable(void);
898
899/****************************************************************************/
900/**
901* @brief Disables DDR SW phase alignment interrupt
902*/
903/****************************************************************************/
904static inline void chipcHw_ddrPhaseAlignInterruptDisable(void);
905
906/****************************************************************************/
907/**
908* @brief Set VPM SW phase alignment interrupt mode
909*
910* This function sets VPM phase alignment interrupt
911*
912*/
913/****************************************************************************/
914static inline void
915chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode);
916
917/****************************************************************************/
918/**
919* @brief Enable DDR phase alignment in software
920*
921*/
922/****************************************************************************/
923static inline void chipcHw_ddrSwPhaseAlignEnable(void);
924
925/****************************************************************************/
926/**
927* @brief Disable DDR phase alignment in software
928*
929*/
930/****************************************************************************/
931static inline void chipcHw_ddrSwPhaseAlignDisable(void);
932
933/****************************************************************************/
934/**
935* @brief Enable DDR phase alignment in hardware
936*
937*/
938/****************************************************************************/
939static inline void chipcHw_ddrHwPhaseAlignEnable(void);
940
941/****************************************************************************/
942/**
943* @brief Disable DDR phase alignment in hardware
944*
945*/
946/****************************************************************************/
947static inline void chipcHw_ddrHwPhaseAlignDisable(void);
948
949/****************************************************************************/
950/**
951* @brief Enable VPM phase alignment in software
952*
953*/
954/****************************************************************************/
955static inline void chipcHw_vpmSwPhaseAlignEnable(void);
956
957/****************************************************************************/
958/**
959* @brief Disable VPM phase alignment in software
960*
961*/
962/****************************************************************************/
963static inline void chipcHw_vpmSwPhaseAlignDisable(void);
964
965/****************************************************************************/
966/**
967* @brief Enable VPM phase alignment in hardware
968*
969*/
970/****************************************************************************/
971static inline void chipcHw_vpmHwPhaseAlignEnable(void);
972
973/****************************************************************************/
974/**
975* @brief Disable VPM phase alignment in hardware
976*
977*/
978/****************************************************************************/
979static inline void chipcHw_vpmHwPhaseAlignDisable(void);
980
981/****************************************************************************/
982/**
983* @brief Set DDR phase alignment margin in hardware
984*
985*/
986/****************************************************************************/
987static inline void chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin /* Margin alinging DDR phase */
988 );
989
990/****************************************************************************/
991/**
992* @brief Set VPM phase alignment margin in hardware
993*
994*/
995/****************************************************************************/
996static inline void chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin /* Margin alinging VPM phase */
997 );
998
999/****************************************************************************/
1000/**
1001* @brief Checks DDR phase aligned status done by HW
1002*
1003* @return 1: When aligned
1004* 0: When not aligned
1005*/
1006/****************************************************************************/
1007static inline uint32_t chipcHw_isDdrHwPhaseAligned(void);
1008
1009/****************************************************************************/
1010/**
1011* @brief Checks VPM phase aligned status done by HW
1012*
1013* @return 1: When aligned
1014* 0: When not aligned
1015*/
1016/****************************************************************************/
1017static inline uint32_t chipcHw_isVpmHwPhaseAligned(void);
1018
1019/****************************************************************************/
1020/**
1021* @brief Get DDR phase aligned status done by HW
1022*
1023*/
1024/****************************************************************************/
1025static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void);
1026
1027/****************************************************************************/
1028/**
1029* @brief Get VPM phase aligned status done by HW
1030*
1031*/
1032/****************************************************************************/
1033static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void);
1034
1035/****************************************************************************/
1036/**
1037* @brief Get DDR phase control value
1038*
1039*/
1040/****************************************************************************/
1041static inline uint32_t chipcHw_getDdrPhaseControl(void);
1042
1043/****************************************************************************/
1044/**
1045* @brief Get VPM phase control value
1046*
1047*/
1048/****************************************************************************/
1049static inline uint32_t chipcHw_getVpmPhaseControl(void);
1050
1051/****************************************************************************/
1052/**
1053* @brief DDR phase alignment timeout count
1054*
1055* @note If HW fails to perform the phase alignment, it will trigger
1056* a DDR phase alignment timeout interrupt.
1057*/
1058/****************************************************************************/
1059static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle /* Timeout in bus cycle */
1060 );
1061
1062/****************************************************************************/
1063/**
1064* @brief VPM phase alignment timeout count
1065*
1066* @note If HW fails to perform the phase alignment, it will trigger
1067* a VPM phase alignment timeout interrupt.
1068*/
1069/****************************************************************************/
1070static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle /* Timeout in bus cycle */
1071 );
1072
1073/****************************************************************************/
1074/**
1075* @brief DDR phase alignment timeout interrupt enable
1076*
1077*/
1078/****************************************************************************/
1079static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void);
1080
1081/****************************************************************************/
1082/**
1083* @brief VPM phase alignment timeout interrupt enable
1084*
1085*/
1086/****************************************************************************/
1087static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void);
1088
1089/****************************************************************************/
1090/**
1091* @brief DDR phase alignment timeout interrupt disable
1092*
1093*/
1094/****************************************************************************/
1095static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void);
1096
1097/****************************************************************************/
1098/**
1099* @brief VPM phase alignment timeout interrupt disable
1100*
1101*/
1102/****************************************************************************/
1103static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void);
1104
1105/****************************************************************************/
1106/**
1107* @brief Clear DDR phase alignment timeout interrupt
1108*
1109*/
1110/****************************************************************************/
1111static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void);
1112
1113/****************************************************************************/
1114/**
1115* @brief Clear VPM phase alignment timeout interrupt
1116*
1117*/
1118/****************************************************************************/
1119static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void);
1120
1121/* ---- Private Constants and Types -------------------------------------- */
1122
1123#endif /* CHIPC_DEF_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
new file mode 100644
index 000000000000..c78833acb37a
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
@@ -0,0 +1,1673 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef CHIPC_INLINE_H
16#define CHIPC_INLINE_H
17
18/* ---- Include Files ----------------------------------------------------- */
19
20#include <csp/errno.h>
21#include <csp/reg.h>
22#include <mach/csp/chipcHw_reg.h>
23#include <mach/csp/chipcHw_def.h>
24
25/* ---- Private Constants and Types --------------------------------------- */
26typedef enum {
27 chipcHw_OPTYPE_BYPASS, /* Bypass operation */
28 chipcHw_OPTYPE_OUTPUT /* Output operation */
29} chipcHw_OPTYPE_e;
30
31/* ---- Public Constants and Types ---------------------------------------- */
32/* ---- Public Variable Externs ------------------------------------------- */
33/* ---- Public Function Prototypes ---------------------------------------- */
34/* ---- Private Function Prototypes --------------------------------------- */
35static inline void chipcHw_setClock(chipcHw_CLOCK_e clock,
36 chipcHw_OPTYPE_e type, int mode);
37
38/****************************************************************************/
39/**
40* @brief Get Numeric Chip ID
41*
42* This function returns Chip ID that includes the revison number
43*
44* @return Complete numeric Chip ID
45*
46*/
47/****************************************************************************/
48static inline uint32_t chipcHw_getChipId(void)
49{
50 return pChipcHw->ChipId;
51}
52
53/****************************************************************************/
54/**
55* @brief Enable Spread Spectrum
56*
57* @note chipcHw_Init() must be called earlier
58*/
59/****************************************************************************/
60static inline void chipcHw_enableSpreadSpectrum(void)
61{
62 if ((pChipcHw->
63 PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) !=
64 chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
65 ddrcReg_PHY_ADDR_CTL_REGP->ssCfg =
66 (0xFFFF << ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT) |
67 (ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK <<
68 ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT);
69 ddrcReg_PHY_ADDR_CTL_REGP->ssCtl |=
70 ddrcReg_PHY_ADDR_SS_CTRL_ENABLE;
71 }
72}
73
74/****************************************************************************/
75/**
76* @brief Disable Spread Spectrum
77*
78*/
79/****************************************************************************/
80static inline void chipcHw_disableSpreadSpectrum(void)
81{
82 ddrcReg_PHY_ADDR_CTL_REGP->ssCtl &= ~ddrcReg_PHY_ADDR_SS_CTRL_ENABLE;
83}
84
85/****************************************************************************/
86/**
87* @brief Get Chip Product ID
88*
89* This function returns Chip Product ID
90*
91* @return Chip Product ID
92*/
93/****************************************************************************/
94static inline uint32_t chipcHw_getChipProductId(void)
95{
96 return (pChipcHw->
97 ChipId & chipcHw_REG_CHIPID_BASE_MASK) >>
98 chipcHw_REG_CHIPID_BASE_SHIFT;
99}
100
101/****************************************************************************/
102/**
103* @brief Get revision number
104*
105* This function returns revision number of the chip
106*
107* @return Revision number
108*/
109/****************************************************************************/
110static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void)
111{
112 return pChipcHw->ChipId & chipcHw_REG_CHIPID_REV_MASK;
113}
114
115/****************************************************************************/
116/**
117* @brief Enables bus interface clock
118*
119* Enables bus interface clock of various device
120*
121* @return void
122*
123* @note use chipcHw_REG_BUS_CLOCK_XXXX for mask
124*/
125/****************************************************************************/
126static inline void chipcHw_busInterfaceClockEnable(uint32_t mask)
127{
128 reg32_modify_or(&pChipcHw->BusIntfClock, mask);
129}
130
131/****************************************************************************/
132/**
133* @brief Disables bus interface clock
134*
135* Disables bus interface clock of various device
136*
137* @return void
138*
139* @note use chipcHw_REG_BUS_CLOCK_XXXX
140*/
141/****************************************************************************/
142static inline void chipcHw_busInterfaceClockDisable(uint32_t mask)
143{
144 reg32_modify_and(&pChipcHw->BusIntfClock, ~mask);
145}
146
147/****************************************************************************/
148/**
149* @brief Get status (enabled/disabled) of bus interface clock
150*
151* This function returns the status of devices' bus interface clock
152*
153* @return Bus interface clock
154*
155*/
156/****************************************************************************/
157static inline uint32_t chipcHw_getBusInterfaceClockStatus(void)
158{
159 return pChipcHw->BusIntfClock;
160}
161
162/****************************************************************************/
163/**
164* @brief Enables various audio channels
165*
166* Enables audio channel
167*
168* @return void
169*
170* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
171*/
172/****************************************************************************/
173static inline void chipcHw_audioChannelEnable(uint32_t mask)
174{
175 reg32_modify_or(&pChipcHw->AudioEnable, mask);
176}
177
178/****************************************************************************/
179/**
180* @brief Disables various audio channels
181*
182* Disables audio channel
183*
184* @return void
185*
186* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
187*/
188/****************************************************************************/
189static inline void chipcHw_audioChannelDisable(uint32_t mask)
190{
191 reg32_modify_and(&pChipcHw->AudioEnable, ~mask);
192}
193
194/****************************************************************************/
195/**
196* @brief Soft resets devices
197*
198* Soft resets various devices
199*
200* @return void
201*
202* @note use chipcHw_REG_SOFT_RESET_XXXXXX defines
203*/
204/****************************************************************************/
205static inline void chipcHw_softReset(uint64_t mask)
206{
207 chipcHw_softResetEnable(mask);
208 chipcHw_softResetDisable(mask);
209}
210
211static inline void chipcHw_softResetDisable(uint64_t mask)
212{
213 uint32_t ctrl1 = (uint32_t) mask;
214 uint32_t ctrl2 = (uint32_t) (mask >> 32);
215
216 /* Deassert module soft reset */
217 REG_LOCAL_IRQ_SAVE;
218 pChipcHw->SoftReset1 ^= ctrl1;
219 pChipcHw->SoftReset2 ^= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK));
220 REG_LOCAL_IRQ_RESTORE;
221}
222
223static inline void chipcHw_softResetEnable(uint64_t mask)
224{
225 uint32_t ctrl1 = (uint32_t) mask;
226 uint32_t ctrl2 = (uint32_t) (mask >> 32);
227 uint32_t unhold = 0;
228
229 REG_LOCAL_IRQ_SAVE;
230 pChipcHw->SoftReset1 |= ctrl1;
231 /* Mask out unhold request bits */
232 pChipcHw->SoftReset2 |= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK));
233
234 /* Process unhold requests */
235 if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD) {
236 unhold = chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD;
237 }
238
239 if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_UNHOLD) {
240 unhold |= chipcHw_REG_SOFT_RESET_VPM_HOLD;
241 }
242
243 if (ctrl2 & chipcHw_REG_SOFT_RESET_ARM_UNHOLD) {
244 unhold |= chipcHw_REG_SOFT_RESET_ARM_HOLD;
245 }
246
247 if (unhold) {
248 /* Make sure unhold request is effective */
249 pChipcHw->SoftReset1 &= ~unhold;
250 }
251 REG_LOCAL_IRQ_RESTORE;
252}
253
254/****************************************************************************/
255/**
256* @brief Configures misc CHIP functionality
257*
258* Configures CHIP functionality
259*
260* @return void
261*
262* @note use chipcHw_REG_MISC_CTRL_XXXXXX
263*/
264/****************************************************************************/
265static inline void chipcHw_miscControl(uint32_t mask)
266{
267 reg32_write(&pChipcHw->MiscCtrl, mask);
268}
269
270static inline void chipcHw_miscControlDisable(uint32_t mask)
271{
272 reg32_modify_and(&pChipcHw->MiscCtrl, ~mask);
273}
274
275static inline void chipcHw_miscControlEnable(uint32_t mask)
276{
277 reg32_modify_or(&pChipcHw->MiscCtrl, mask);
278}
279
280/****************************************************************************/
281/**
282* @brief Set OTP options
283*
284* Set OTP options
285*
286* @return void
287*
288* @note use chipcHw_REG_OTP_XXXXXX
289*/
290/****************************************************************************/
291static inline void chipcHw_setOTPOption(uint64_t mask)
292{
293 uint32_t ctrl1 = (uint32_t) mask;
294 uint32_t ctrl2 = (uint32_t) (mask >> 32);
295
296 reg32_modify_or(&pChipcHw->SoftOTP1, ctrl1);
297 reg32_modify_or(&pChipcHw->SoftOTP2, ctrl2);
298}
299
300/****************************************************************************/
301/**
302* @brief Get sticky bits
303*
304* @return Sticky bit options of type chipcHw_REG_STICKY_XXXXXX
305*
306*/
307/****************************************************************************/
308static inline uint32_t chipcHw_getStickyBits(void)
309{
310 return pChipcHw->Sticky;
311}
312
313/****************************************************************************/
314/**
315* @brief Set sticky bits
316*
317* @return void
318*
319* @note use chipcHw_REG_STICKY_XXXXXX
320*/
321/****************************************************************************/
322static inline void chipcHw_setStickyBits(uint32_t mask)
323{
324 uint32_t bits = 0;
325
326 REG_LOCAL_IRQ_SAVE;
327 if (mask & chipcHw_REG_STICKY_POR_BROM) {
328 bits |= chipcHw_REG_STICKY_POR_BROM;
329 } else {
330 uint32_t sticky;
331 sticky = pChipcHw->Sticky;
332
333 if ((mask & chipcHw_REG_STICKY_BOOT_DONE)
334 && (sticky & chipcHw_REG_STICKY_BOOT_DONE) == 0) {
335 bits |= chipcHw_REG_STICKY_BOOT_DONE;
336 }
337 if ((mask & chipcHw_REG_STICKY_GENERAL_1)
338 && (sticky & chipcHw_REG_STICKY_GENERAL_1) == 0) {
339 bits |= chipcHw_REG_STICKY_GENERAL_1;
340 }
341 if ((mask & chipcHw_REG_STICKY_GENERAL_2)
342 && (sticky & chipcHw_REG_STICKY_GENERAL_2) == 0) {
343 bits |= chipcHw_REG_STICKY_GENERAL_2;
344 }
345 if ((mask & chipcHw_REG_STICKY_GENERAL_3)
346 && (sticky & chipcHw_REG_STICKY_GENERAL_3) == 0) {
347 bits |= chipcHw_REG_STICKY_GENERAL_3;
348 }
349 if ((mask & chipcHw_REG_STICKY_GENERAL_4)
350 && (sticky & chipcHw_REG_STICKY_GENERAL_4) == 0) {
351 bits |= chipcHw_REG_STICKY_GENERAL_4;
352 }
353 if ((mask & chipcHw_REG_STICKY_GENERAL_5)
354 && (sticky & chipcHw_REG_STICKY_GENERAL_5) == 0) {
355 bits |= chipcHw_REG_STICKY_GENERAL_5;
356 }
357 }
358 pChipcHw->Sticky = bits;
359 REG_LOCAL_IRQ_RESTORE;
360}
361
362/****************************************************************************/
363/**
364* @brief Clear sticky bits
365*
366* @return void
367*
368* @note use chipcHw_REG_STICKY_XXXXXX
369*/
370/****************************************************************************/
371static inline void chipcHw_clearStickyBits(uint32_t mask)
372{
373 uint32_t bits = 0;
374
375 REG_LOCAL_IRQ_SAVE;
376 if (mask &
377 (chipcHw_REG_STICKY_BOOT_DONE | chipcHw_REG_STICKY_GENERAL_1 |
378 chipcHw_REG_STICKY_GENERAL_2 | chipcHw_REG_STICKY_GENERAL_3 |
379 chipcHw_REG_STICKY_GENERAL_4 | chipcHw_REG_STICKY_GENERAL_5)) {
380 uint32_t sticky = pChipcHw->Sticky;
381
382 if ((mask & chipcHw_REG_STICKY_BOOT_DONE)
383 && (sticky & chipcHw_REG_STICKY_BOOT_DONE)) {
384 bits = chipcHw_REG_STICKY_BOOT_DONE;
385 mask &= ~chipcHw_REG_STICKY_BOOT_DONE;
386 }
387 if ((mask & chipcHw_REG_STICKY_GENERAL_1)
388 && (sticky & chipcHw_REG_STICKY_GENERAL_1)) {
389 bits |= chipcHw_REG_STICKY_GENERAL_1;
390 mask &= ~chipcHw_REG_STICKY_GENERAL_1;
391 }
392 if ((mask & chipcHw_REG_STICKY_GENERAL_2)
393 && (sticky & chipcHw_REG_STICKY_GENERAL_2)) {
394 bits |= chipcHw_REG_STICKY_GENERAL_2;
395 mask &= ~chipcHw_REG_STICKY_GENERAL_2;
396 }
397 if ((mask & chipcHw_REG_STICKY_GENERAL_3)
398 && (sticky & chipcHw_REG_STICKY_GENERAL_3)) {
399 bits |= chipcHw_REG_STICKY_GENERAL_3;
400 mask &= ~chipcHw_REG_STICKY_GENERAL_3;
401 }
402 if ((mask & chipcHw_REG_STICKY_GENERAL_4)
403 && (sticky & chipcHw_REG_STICKY_GENERAL_4)) {
404 bits |= chipcHw_REG_STICKY_GENERAL_4;
405 mask &= ~chipcHw_REG_STICKY_GENERAL_4;
406 }
407 if ((mask & chipcHw_REG_STICKY_GENERAL_5)
408 && (sticky & chipcHw_REG_STICKY_GENERAL_5)) {
409 bits |= chipcHw_REG_STICKY_GENERAL_5;
410 mask &= ~chipcHw_REG_STICKY_GENERAL_5;
411 }
412 }
413 pChipcHw->Sticky = bits | mask;
414 REG_LOCAL_IRQ_RESTORE;
415}
416
417/****************************************************************************/
418/**
419* @brief Get software strap value
420*
421* Retrieves software strap value
422*
423* @return Software strap value
424*
425*/
426/****************************************************************************/
427static inline uint32_t chipcHw_getSoftStraps(void)
428{
429 return pChipcHw->SoftStraps;
430}
431
432/****************************************************************************/
433/**
434* @brief Set software override strap options
435*
436* set software override strap options
437*
438* @return nothing
439*
440*/
441/****************************************************************************/
442static inline void chipcHw_setSoftStraps(uint32_t strapOptions)
443{
444 reg32_write(&pChipcHw->SoftStraps, strapOptions);
445}
446
447/****************************************************************************/
448/**
449* @brief Get Pin Strap Options
450*
451* This function returns the raw boot strap options
452*
453* @return strap options
454*
455*/
456/****************************************************************************/
457static inline uint32_t chipcHw_getPinStraps(void)
458{
459 return pChipcHw->PinStraps;
460}
461
462/****************************************************************************/
463/**
464* @brief Get Valid Strap Options
465*
466* This function returns the valid raw boot strap options
467*
468* @return strap options
469*
470*/
471/****************************************************************************/
472static inline uint32_t chipcHw_getValidStraps(void)
473{
474 uint32_t softStraps;
475
476 /*
477 ** Always return the SoftStraps - bootROM calls chipcHw_initValidStraps
478 ** which copies HW straps to soft straps if there is no override
479 */
480 softStraps = chipcHw_getSoftStraps();
481
482 return softStraps;
483}
484
485/****************************************************************************/
486/**
487* @brief Initialize valid pin strap options
488*
489* Retrieves valid pin strap options by copying HW strap options to soft register
490* (if chipcHw_STRAPS_SOFT_OVERRIDE not set)
491*
492* @return nothing
493*
494*/
495/****************************************************************************/
496static inline void chipcHw_initValidStraps(void)
497{
498 uint32_t softStraps;
499
500 REG_LOCAL_IRQ_SAVE;
501 softStraps = chipcHw_getSoftStraps();
502
503 if ((softStraps & chipcHw_STRAPS_SOFT_OVERRIDE) == 0) {
504 /* Copy HW straps to software straps */
505 chipcHw_setSoftStraps(chipcHw_getPinStraps());
506 }
507 REG_LOCAL_IRQ_RESTORE;
508}
509
510/****************************************************************************/
511/**
512* @brief Get boot device
513*
514* This function returns the device type used in booting the system
515*
516* @return Boot device of type chipcHw_BOOT_DEVICE
517*
518*/
519/****************************************************************************/
520static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void)
521{
522 return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_DEVICE_MASK;
523}
524
525/****************************************************************************/
526/**
527* @brief Get boot mode
528*
529* This function returns the way the system was booted
530*
531* @return Boot mode of type chipcHw_BOOT_MODE
532*
533*/
534/****************************************************************************/
535static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void)
536{
537 return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_MODE_MASK;
538}
539
540/****************************************************************************/
541/**
542* @brief Get NAND flash page size
543*
544* This function returns the NAND device page size
545*
546* @return Boot NAND device page size
547*
548*/
549/****************************************************************************/
550static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void)
551{
552 return chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_PAGESIZE_MASK;
553}
554
555/****************************************************************************/
556/**
557* @brief Get NAND flash address cycle configuration
558*
559* This function returns the NAND flash address cycle configuration
560*
561* @return 0 = Do not extra address cycle, 1 = Add extra cycle
562*
563*/
564/****************************************************************************/
565static inline int chipcHw_getNandExtraCycle(void)
566{
567 if (chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_EXTRA_CYCLE) {
568 return 1;
569 } else {
570 return 0;
571 }
572}
573
574/****************************************************************************/
575/**
576* @brief Activates PIF interface
577*
578* This function activates PIF interface by taking control of LCD pins
579*
580* @note
581* When activated, LCD pins will be defined as follows for PIF operation
582*
583* CLD[17:0] = pif_data[17:0]
584* CLD[23:18] = pif_address[5:0]
585* CLPOWER = pif_wr_str
586* CLCP = pif_rd_str
587* CLAC = pif_hat1
588* CLFP = pif_hrdy1
589* CLLP = pif_hat2
590* GPIO[42] = pif_hrdy2
591*
592* In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin
593*
594*/
595/****************************************************************************/
596static inline void chipcHw_activatePifInterface(void)
597{
598 reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_PIF_PIN_ENABLE);
599}
600
601/****************************************************************************/
602/**
603* @brief Activates LCD interface
604*
605* This function activates LCD interface
606*
607* @note
608* When activated, LCD pins will be defined as follows
609*
610* CLD[17:0] = LCD data
611* CLD[23:18] = LCD data
612* CLPOWER = LCD power
613* CLCP =
614* CLAC = LCD ack
615* CLFP =
616* CLLP =
617*/
618/****************************************************************************/
619static inline void chipcHw_activateLcdInterface(void)
620{
621 reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_LCD_PIN_ENABLE);
622}
623
624/****************************************************************************/
625/**
626* @brief Deactivates PIF/LCD interface
627*
628* This function deactivates PIF/LCD interface
629*
630* @note
631* When deactivated LCD pins will be in rti-stated
632*
633*/
634/****************************************************************************/
635static inline void chipcHw_deactivatePifLcdInterface(void)
636{
637 reg32_write(&pChipcHw->LcdPifMode, 0);
638}
639
640/****************************************************************************/
641/**
642* @brief Select GE2
643*
644* This function select GE2 as the graphic engine
645*
646*/
647/****************************************************************************/
648static inline void chipcHw_selectGE2(void)
649{
650 reg32_modify_and(&pChipcHw->MiscCtrl, ~chipcHw_REG_MISC_CTRL_GE_SEL);
651}
652
653/****************************************************************************/
654/**
655* @brief Select GE3
656*
657* This function select GE3 as the graphic engine
658*
659*/
660/****************************************************************************/
661static inline void chipcHw_selectGE3(void)
662{
663 reg32_modify_or(&pChipcHw->MiscCtrl, chipcHw_REG_MISC_CTRL_GE_SEL);
664}
665
666/****************************************************************************/
667/**
668* @brief Get to know the configuration of GPIO pin
669*
670*/
671/****************************************************************************/
672static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin)
673{
674 return (*((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &
675 (chipcHw_REG_GPIO_MUX_MASK <<
676 chipcHw_REG_GPIO_MUX_POSITION(pin))) >>
677 chipcHw_REG_GPIO_MUX_POSITION(pin);
678}
679
680/****************************************************************************/
681/**
682* @brief Configure GPIO pin function
683*
684*/
685/****************************************************************************/
686static inline void chipcHw_setGpioPinFunction(int pin,
687 chipcHw_GPIO_FUNCTION_e func)
688{
689 REG_LOCAL_IRQ_SAVE;
690 *((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &=
691 ~(chipcHw_REG_GPIO_MUX_MASK << chipcHw_REG_GPIO_MUX_POSITION(pin));
692 *((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) |=
693 func << chipcHw_REG_GPIO_MUX_POSITION(pin);
694 REG_LOCAL_IRQ_RESTORE;
695}
696
697/****************************************************************************/
698/**
699* @brief Set Pin slew rate
700*
701* This function sets the slew of individual pin
702*
703*/
704/****************************************************************************/
705static inline void chipcHw_setPinSlewRate(uint32_t pin,
706 chipcHw_PIN_SLEW_RATE_e slewRate)
707{
708 REG_LOCAL_IRQ_SAVE;
709 *((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) &=
710 ~(chipcHw_REG_SLEW_RATE_MASK <<
711 chipcHw_REG_SLEW_RATE_POSITION(pin));
712 *((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) |=
713 (uint32_t) slewRate << chipcHw_REG_SLEW_RATE_POSITION(pin);
714 REG_LOCAL_IRQ_RESTORE;
715}
716
717/****************************************************************************/
718/**
719* @brief Set Pin output drive current
720*
721* This function sets output drive current of individual pin
722*
723* Note: Avoid the use of the word 'current' since linux headers define this
724* to be the current task.
725*/
726/****************************************************************************/
727static inline void chipcHw_setPinOutputCurrent(uint32_t pin,
728 chipcHw_PIN_CURRENT_STRENGTH_e
729 curr)
730{
731 REG_LOCAL_IRQ_SAVE;
732 *((uint32_t *) chipcHw_REG_CURRENT(pin)) &=
733 ~(chipcHw_REG_CURRENT_MASK << chipcHw_REG_CURRENT_POSITION(pin));
734 *((uint32_t *) chipcHw_REG_CURRENT(pin)) |=
735 (uint32_t) curr << chipcHw_REG_CURRENT_POSITION(pin);
736 REG_LOCAL_IRQ_RESTORE;
737}
738
739/****************************************************************************/
740/**
741* @brief Set Pin pullup register
742*
743* This function sets pullup register of individual pin
744*
745*/
746/****************************************************************************/
747static inline void chipcHw_setPinPullup(uint32_t pin, chipcHw_PIN_PULL_e pullup)
748{
749 REG_LOCAL_IRQ_SAVE;
750 *((uint32_t *) chipcHw_REG_PULLUP(pin)) &=
751 ~(chipcHw_REG_PULLUP_MASK << chipcHw_REG_PULLUP_POSITION(pin));
752 *((uint32_t *) chipcHw_REG_PULLUP(pin)) |=
753 (uint32_t) pullup << chipcHw_REG_PULLUP_POSITION(pin);
754 REG_LOCAL_IRQ_RESTORE;
755}
756
757/****************************************************************************/
758/**
759* @brief Set Pin input type
760*
761* This function sets input type of individual pin
762*
763*/
764/****************************************************************************/
765static inline void chipcHw_setPinInputType(uint32_t pin,
766 chipcHw_PIN_INPUTTYPE_e inputType)
767{
768 REG_LOCAL_IRQ_SAVE;
769 *((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) &=
770 ~(chipcHw_REG_INPUTTYPE_MASK <<
771 chipcHw_REG_INPUTTYPE_POSITION(pin));
772 *((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) |=
773 (uint32_t) inputType << chipcHw_REG_INPUTTYPE_POSITION(pin);
774 REG_LOCAL_IRQ_RESTORE;
775}
776
777/****************************************************************************/
778/**
779* @brief Power up the USB PHY
780*
781* This function powers up the USB PHY
782*
783*/
784/****************************************************************************/
785static inline void chipcHw_powerUpUsbPhy(void)
786{
787 reg32_modify_and(&pChipcHw->MiscCtrl,
788 chipcHw_REG_MISC_CTRL_USB_POWERON);
789}
790
791/****************************************************************************/
792/**
793* @brief Power down the USB PHY
794*
795* This function powers down the USB PHY
796*
797*/
798/****************************************************************************/
799static inline void chipcHw_powerDownUsbPhy(void)
800{
801 reg32_modify_or(&pChipcHw->MiscCtrl,
802 chipcHw_REG_MISC_CTRL_USB_POWEROFF);
803}
804
805/****************************************************************************/
806/**
807* @brief Set the 2nd USB as host
808*
809* This function sets the 2nd USB as host
810*
811*/
812/****************************************************************************/
813static inline void chipcHw_setUsbHost(void)
814{
815 reg32_modify_or(&pChipcHw->MiscCtrl,
816 chipcHw_REG_MISC_CTRL_USB_MODE_HOST);
817}
818
819/****************************************************************************/
820/**
821* @brief Set the 2nd USB as device
822*
823* This function sets the 2nd USB as device
824*
825*/
826/****************************************************************************/
827static inline void chipcHw_setUsbDevice(void)
828{
829 reg32_modify_and(&pChipcHw->MiscCtrl,
830 chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE);
831}
832
833/****************************************************************************/
834/**
835* @brief Lower layer funtion to enable/disable a clock of a certain device
836*
837* This function enables/disables a core clock
838*
839*/
840/****************************************************************************/
841static inline void chipcHw_setClock(chipcHw_CLOCK_e clock,
842 chipcHw_OPTYPE_e type, int mode)
843{
844 volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
845 volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
846
847 switch (clock) {
848 case chipcHw_CLOCK_DDR:
849 pPLLReg = &pChipcHw->DDRClock;
850 break;
851 case chipcHw_CLOCK_ARM:
852 pPLLReg = &pChipcHw->ARMClock;
853 break;
854 case chipcHw_CLOCK_ESW:
855 pPLLReg = &pChipcHw->ESWClock;
856 break;
857 case chipcHw_CLOCK_VPM:
858 pPLLReg = &pChipcHw->VPMClock;
859 break;
860 case chipcHw_CLOCK_ESW125:
861 pPLLReg = &pChipcHw->ESW125Clock;
862 break;
863 case chipcHw_CLOCK_UART:
864 pPLLReg = &pChipcHw->UARTClock;
865 break;
866 case chipcHw_CLOCK_SDIO0:
867 pPLLReg = &pChipcHw->SDIO0Clock;
868 break;
869 case chipcHw_CLOCK_SDIO1:
870 pPLLReg = &pChipcHw->SDIO1Clock;
871 break;
872 case chipcHw_CLOCK_SPI:
873 pPLLReg = &pChipcHw->SPIClock;
874 break;
875 case chipcHw_CLOCK_ETM:
876 pPLLReg = &pChipcHw->ETMClock;
877 break;
878 case chipcHw_CLOCK_USB:
879 pPLLReg = &pChipcHw->USBClock;
880 if (type == chipcHw_OPTYPE_OUTPUT) {
881 if (mode) {
882 reg32_modify_and(pPLLReg,
883 ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
884 } else {
885 reg32_modify_or(pPLLReg,
886 chipcHw_REG_PLL_CLOCK_POWER_DOWN);
887 }
888 }
889 break;
890 case chipcHw_CLOCK_LCD:
891 pPLLReg = &pChipcHw->LCDClock;
892 if (type == chipcHw_OPTYPE_OUTPUT) {
893 if (mode) {
894 reg32_modify_and(pPLLReg,
895 ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
896 } else {
897 reg32_modify_or(pPLLReg,
898 chipcHw_REG_PLL_CLOCK_POWER_DOWN);
899 }
900 }
901 break;
902 case chipcHw_CLOCK_APM:
903 pPLLReg = &pChipcHw->APMClock;
904 if (type == chipcHw_OPTYPE_OUTPUT) {
905 if (mode) {
906 reg32_modify_and(pPLLReg,
907 ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
908 } else {
909 reg32_modify_or(pPLLReg,
910 chipcHw_REG_PLL_CLOCK_POWER_DOWN);
911 }
912 }
913 break;
914 case chipcHw_CLOCK_BUS:
915 pClockCtrl = &pChipcHw->ACLKClock;
916 break;
917 case chipcHw_CLOCK_OTP:
918 pClockCtrl = &pChipcHw->OTPClock;
919 break;
920 case chipcHw_CLOCK_I2C:
921 pClockCtrl = &pChipcHw->I2CClock;
922 break;
923 case chipcHw_CLOCK_I2S0:
924 pClockCtrl = &pChipcHw->I2S0Clock;
925 break;
926 case chipcHw_CLOCK_RTBUS:
927 pClockCtrl = &pChipcHw->RTBUSClock;
928 break;
929 case chipcHw_CLOCK_APM100:
930 pClockCtrl = &pChipcHw->APM100Clock;
931 break;
932 case chipcHw_CLOCK_TSC:
933 pClockCtrl = &pChipcHw->TSCClock;
934 break;
935 case chipcHw_CLOCK_LED:
936 pClockCtrl = &pChipcHw->LEDClock;
937 break;
938 case chipcHw_CLOCK_I2S1:
939 pClockCtrl = &pChipcHw->I2S1Clock;
940 break;
941 }
942
943 if (pPLLReg) {
944 switch (type) {
945 case chipcHw_OPTYPE_OUTPUT:
946 /* PLL clock output enable/disable */
947 if (mode) {
948 if (clock == chipcHw_CLOCK_DDR) {
949 /* DDR clock enable is inverted */
950 reg32_modify_and(pPLLReg,
951 ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
952 } else {
953 reg32_modify_or(pPLLReg,
954 chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
955 }
956 } else {
957 if (clock == chipcHw_CLOCK_DDR) {
958 /* DDR clock disable is inverted */
959 reg32_modify_or(pPLLReg,
960 chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
961 } else {
962 reg32_modify_and(pPLLReg,
963 ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
964 }
965 }
966 break;
967 case chipcHw_OPTYPE_BYPASS:
968 /* PLL clock bypass enable/disable */
969 if (mode) {
970 reg32_modify_or(pPLLReg,
971 chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
972 } else {
973 reg32_modify_and(pPLLReg,
974 ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
975 }
976 break;
977 }
978 } else if (pClockCtrl) {
979 switch (type) {
980 case chipcHw_OPTYPE_OUTPUT:
981 if (mode) {
982 reg32_modify_or(pClockCtrl,
983 chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE);
984 } else {
985 reg32_modify_and(pClockCtrl,
986 ~chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE);
987 }
988 break;
989 case chipcHw_OPTYPE_BYPASS:
990 if (mode) {
991 reg32_modify_or(pClockCtrl,
992 chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
993 } else {
994 reg32_modify_and(pClockCtrl,
995 ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
996 }
997 break;
998 }
999 }
1000}
1001
1002/****************************************************************************/
1003/**
1004* @brief Disables a core clock of a certain device
1005*
1006* This function disables a core clock
1007*
1008* @note no change in power consumption
1009*/
1010/****************************************************************************/
1011static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock)
1012{
1013
1014 /* Disable output of the clock */
1015 chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 0);
1016}
1017
1018/****************************************************************************/
1019/**
1020* @brief Enable a core clock of a certain device
1021*
1022* This function enables a core clock
1023*
1024* @note no change in power consumption
1025*/
1026/****************************************************************************/
1027static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock)
1028{
1029
1030 /* Enable output of the clock */
1031 chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 1);
1032}
1033
1034/****************************************************************************/
1035/**
1036* @brief Enables bypass clock of a certain device
1037*
1038* This function enables bypass clock
1039*
1040* @note Doesnot affect the bus interface clock
1041*/
1042/****************************************************************************/
1043static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock)
1044{
1045 /* Enable bypass clock */
1046 chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 1);
1047}
1048
1049/****************************************************************************/
1050/**
1051* @brief Disabled bypass clock of a certain device
1052*
1053* This function disables bypass clock
1054*
1055* @note Doesnot affect the bus interface clock
1056*/
1057/****************************************************************************/
1058static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock)
1059{
1060 /* Disable bypass clock */
1061 chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 0);
1062
1063}
1064
1065/****************************************************************************/
1066/** @brief Checks if software strap is enabled
1067 *
1068 * @return 1 : When enable
1069 * 0 : When disable
1070 */
1071/****************************************************************************/
1072static inline int chipcHw_isSoftwareStrapsEnable(void)
1073{
1074 return pChipcHw->SoftStraps & 0x00000001;
1075}
1076
1077/****************************************************************************/
1078/** @brief Enable software strap
1079 */
1080/****************************************************************************/
1081static inline void chipcHw_softwareStrapsEnable(void)
1082{
1083 reg32_modify_or(&pChipcHw->SoftStraps, 0x00000001);
1084}
1085
1086/****************************************************************************/
1087/** @brief Disable software strap
1088 */
1089/****************************************************************************/
1090static inline void chipcHw_softwareStrapsDisable(void)
1091{
1092 reg32_modify_and(&pChipcHw->SoftStraps, (~0x00000001));
1093}
1094
1095/****************************************************************************/
1096/** @brief PLL test enable
1097 */
1098/****************************************************************************/
1099static inline void chipcHw_pllTestEnable(void)
1100{
1101 reg32_modify_or(&pChipcHw->PLLConfig,
1102 chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
1103}
1104
1105/****************************************************************************/
1106/** @brief PLL2 test enable
1107 */
1108/****************************************************************************/
1109static inline void chipcHw_pll2TestEnable(void)
1110{
1111 reg32_modify_or(&pChipcHw->PLLConfig2,
1112 chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
1113}
1114
1115/****************************************************************************/
1116/** @brief PLL test disable
1117 */
1118/****************************************************************************/
1119static inline void chipcHw_pllTestDisable(void)
1120{
1121 reg32_modify_and(&pChipcHw->PLLConfig,
1122 ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
1123}
1124
1125/****************************************************************************/
1126/** @brief PLL2 test disable
1127 */
1128/****************************************************************************/
1129static inline void chipcHw_pll2TestDisable(void)
1130{
1131 reg32_modify_and(&pChipcHw->PLLConfig2,
1132 ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
1133}
1134
1135/****************************************************************************/
1136/** @brief Get PLL test status
1137 */
1138/****************************************************************************/
1139static inline int chipcHw_isPllTestEnable(void)
1140{
1141 return pChipcHw->PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_ENABLE;
1142}
1143
1144/****************************************************************************/
1145/** @brief Get PLL2 test status
1146 */
1147/****************************************************************************/
1148static inline int chipcHw_isPll2TestEnable(void)
1149{
1150 return pChipcHw->PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_ENABLE;
1151}
1152
1153/****************************************************************************/
1154/** @brief PLL test select
1155 */
1156/****************************************************************************/
1157static inline void chipcHw_pllTestSelect(uint32_t val)
1158{
1159 REG_LOCAL_IRQ_SAVE;
1160 pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK;
1161 pChipcHw->PLLConfig |=
1162 (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT;
1163 REG_LOCAL_IRQ_RESTORE;
1164}
1165
1166/****************************************************************************/
1167/** @brief PLL2 test select
1168 */
1169/****************************************************************************/
1170static inline void chipcHw_pll2TestSelect(uint32_t val)
1171{
1172
1173 REG_LOCAL_IRQ_SAVE;
1174 pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK;
1175 pChipcHw->PLLConfig2 |=
1176 (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT;
1177 REG_LOCAL_IRQ_RESTORE;
1178}
1179
1180/****************************************************************************/
1181/** @brief Get PLL test selected option
1182 */
1183/****************************************************************************/
1184static inline uint8_t chipcHw_getPllTestSelected(void)
1185{
1186 return (uint8_t) ((pChipcHw->
1187 PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK)
1188 >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT);
1189}
1190
1191/****************************************************************************/
1192/** @brief Get PLL2 test selected option
1193 */
1194/****************************************************************************/
1195static inline uint8_t chipcHw_getPll2TestSelected(void)
1196{
1197 return (uint8_t) ((pChipcHw->
1198 PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK)
1199 >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT);
1200}
1201
1202/****************************************************************************/
1203/**
1204* @brief Disable the PLL1
1205*
1206*/
1207/****************************************************************************/
1208static inline void chipcHw_pll1Disable(void)
1209{
1210 REG_LOCAL_IRQ_SAVE;
1211 pChipcHw->PLLConfig |= chipcHw_REG_PLL_CONFIG_POWER_DOWN;
1212 REG_LOCAL_IRQ_RESTORE;
1213}
1214
1215/****************************************************************************/
1216/**
1217* @brief Disable the PLL2
1218*
1219*/
1220/****************************************************************************/
1221static inline void chipcHw_pll2Disable(void)
1222{
1223 REG_LOCAL_IRQ_SAVE;
1224 pChipcHw->PLLConfig2 |= chipcHw_REG_PLL_CONFIG_POWER_DOWN;
1225 REG_LOCAL_IRQ_RESTORE;
1226}
1227
1228/****************************************************************************/
1229/**
1230* @brief Enables DDR SW phase alignment interrupt
1231*/
1232/****************************************************************************/
1233static inline void chipcHw_ddrPhaseAlignInterruptEnable(void)
1234{
1235 REG_LOCAL_IRQ_SAVE;
1236 pChipcHw->Spare1 |= chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE;
1237 REG_LOCAL_IRQ_RESTORE;
1238}
1239
1240/****************************************************************************/
1241/**
1242* @brief Disables DDR SW phase alignment interrupt
1243*/
1244/****************************************************************************/
1245static inline void chipcHw_ddrPhaseAlignInterruptDisable(void)
1246{
1247 REG_LOCAL_IRQ_SAVE;
1248 pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE;
1249 REG_LOCAL_IRQ_RESTORE;
1250}
1251
1252/****************************************************************************/
1253/**
1254* @brief Set VPM SW phase alignment interrupt mode
1255*
1256* This function sets VPM phase alignment interrupt
1257*/
1258/****************************************************************************/
1259static inline void
1260chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode)
1261{
1262 REG_LOCAL_IRQ_SAVE;
1263 if (mode == chipcHw_VPM_HW_PHASE_INTR_DISABLE) {
1264 pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE;
1265 } else {
1266 pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE;
1267 }
1268 pChipcHw->VPMPhaseCtrl2 =
1269 (pChipcHw->
1270 VPMPhaseCtrl2 & ~(chipcHw_REG_VPM_INTR_SELECT_MASK <<
1271 chipcHw_REG_VPM_INTR_SELECT_SHIFT)) | mode;
1272 REG_LOCAL_IRQ_RESTORE;
1273}
1274
1275/****************************************************************************/
1276/**
1277* @brief Enable DDR phase alignment in software
1278*
1279*/
1280/****************************************************************************/
1281static inline void chipcHw_ddrSwPhaseAlignEnable(void)
1282{
1283 REG_LOCAL_IRQ_SAVE;
1284 pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE;
1285 REG_LOCAL_IRQ_RESTORE;
1286}
1287
1288/****************************************************************************/
1289/**
1290* @brief Disable DDR phase alignment in software
1291*
1292*/
1293/****************************************************************************/
1294static inline void chipcHw_ddrSwPhaseAlignDisable(void)
1295{
1296 REG_LOCAL_IRQ_SAVE;
1297 pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE;
1298 REG_LOCAL_IRQ_RESTORE;
1299}
1300
1301/****************************************************************************/
1302/**
1303* @brief Enable DDR phase alignment in hardware
1304*
1305*/
1306/****************************************************************************/
1307static inline void chipcHw_ddrHwPhaseAlignEnable(void)
1308{
1309 REG_LOCAL_IRQ_SAVE;
1310 pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE;
1311 REG_LOCAL_IRQ_RESTORE;
1312}
1313
1314/****************************************************************************/
1315/**
1316* @brief Disable DDR phase alignment in hardware
1317*
1318*/
1319/****************************************************************************/
1320static inline void chipcHw_ddrHwPhaseAlignDisable(void)
1321{
1322 REG_LOCAL_IRQ_SAVE;
1323 pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE;
1324 REG_LOCAL_IRQ_RESTORE;
1325}
1326
1327/****************************************************************************/
1328/**
1329* @brief Enable VPM phase alignment in software
1330*
1331*/
1332/****************************************************************************/
1333static inline void chipcHw_vpmSwPhaseAlignEnable(void)
1334{
1335 REG_LOCAL_IRQ_SAVE;
1336 pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE;
1337 REG_LOCAL_IRQ_RESTORE;
1338}
1339
1340/****************************************************************************/
1341/**
1342* @brief Disable VPM phase alignment in software
1343*
1344*/
1345/****************************************************************************/
1346static inline void chipcHw_vpmSwPhaseAlignDisable(void)
1347{
1348 REG_LOCAL_IRQ_SAVE;
1349 pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE;
1350 REG_LOCAL_IRQ_RESTORE;
1351}
1352
1353/****************************************************************************/
1354/**
1355* @brief Enable VPM phase alignment in hardware
1356*
1357*/
1358/****************************************************************************/
1359static inline void chipcHw_vpmHwPhaseAlignEnable(void)
1360{
1361 REG_LOCAL_IRQ_SAVE;
1362 pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE;
1363 REG_LOCAL_IRQ_RESTORE;
1364}
1365
1366/****************************************************************************/
1367/**
1368* @brief Disable VPM phase alignment in hardware
1369*
1370*/
1371/****************************************************************************/
1372static inline void chipcHw_vpmHwPhaseAlignDisable(void)
1373{
1374 REG_LOCAL_IRQ_SAVE;
1375 pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE;
1376 REG_LOCAL_IRQ_RESTORE;
1377}
1378
1379/****************************************************************************/
1380/**
1381* @brief Set DDR phase alignment margin in hardware
1382*
1383*/
1384/****************************************************************************/
1385static inline void
1386chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin)
1387{
1388 uint32_t ge = 0;
1389 uint32_t le = 0;
1390
1391 switch (margin) {
1392 case chipcHw_DDR_HW_PHASE_MARGIN_STRICT:
1393 ge = 0x0F;
1394 le = 0x0F;
1395 break;
1396 case chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM:
1397 ge = 0x03;
1398 le = 0x3F;
1399 break;
1400 case chipcHw_DDR_HW_PHASE_MARGIN_WIDE:
1401 ge = 0x01;
1402 le = 0x7F;
1403 break;
1404 }
1405
1406 {
1407 REG_LOCAL_IRQ_SAVE;
1408
1409 pChipcHw->DDRPhaseCtrl1 &=
1410 ~((chipcHw_REG_DDR_PHASE_VALUE_GE_MASK <<
1411 chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT)
1412 || (chipcHw_REG_DDR_PHASE_VALUE_LE_MASK <<
1413 chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT));
1414
1415 pChipcHw->DDRPhaseCtrl1 |=
1416 ((ge << chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT)
1417 || (le << chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT));
1418
1419 REG_LOCAL_IRQ_RESTORE;
1420 }
1421}
1422
1423/****************************************************************************/
1424/**
1425* @brief Set VPM phase alignment margin in hardware
1426*
1427*/
1428/****************************************************************************/
1429static inline void
1430chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin)
1431{
1432 uint32_t ge = 0;
1433 uint32_t le = 0;
1434
1435 switch (margin) {
1436 case chipcHw_VPM_HW_PHASE_MARGIN_STRICT:
1437 ge = 0x0F;
1438 le = 0x0F;
1439 break;
1440 case chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM:
1441 ge = 0x03;
1442 le = 0x3F;
1443 break;
1444 case chipcHw_VPM_HW_PHASE_MARGIN_WIDE:
1445 ge = 0x01;
1446 le = 0x7F;
1447 break;
1448 }
1449
1450 {
1451 REG_LOCAL_IRQ_SAVE;
1452
1453 pChipcHw->VPMPhaseCtrl1 &=
1454 ~((chipcHw_REG_VPM_PHASE_VALUE_GE_MASK <<
1455 chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT)
1456 || (chipcHw_REG_VPM_PHASE_VALUE_LE_MASK <<
1457 chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT));
1458
1459 pChipcHw->VPMPhaseCtrl1 |=
1460 ((ge << chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT)
1461 || (le << chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT));
1462
1463 REG_LOCAL_IRQ_RESTORE;
1464 }
1465}
1466
1467/****************************************************************************/
1468/**
1469* @brief Checks DDR phase aligned status done by HW
1470*
1471* @return 1: When aligned
1472* 0: When not aligned
1473*/
1474/****************************************************************************/
1475static inline uint32_t chipcHw_isDdrHwPhaseAligned(void)
1476{
1477 return (pChipcHw->
1478 PhaseAlignStatus & chipcHw_REG_DDR_PHASE_ALIGNED) ? 1 : 0;
1479}
1480
1481/****************************************************************************/
1482/**
1483* @brief Checks VPM phase aligned status done by HW
1484*
1485* @return 1: When aligned
1486* 0: When not aligned
1487*/
1488/****************************************************************************/
1489static inline uint32_t chipcHw_isVpmHwPhaseAligned(void)
1490{
1491 return (pChipcHw->
1492 PhaseAlignStatus & chipcHw_REG_VPM_PHASE_ALIGNED) ? 1 : 0;
1493}
1494
1495/****************************************************************************/
1496/**
1497* @brief Get DDR phase aligned status done by HW
1498*
1499*/
1500/****************************************************************************/
1501static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void)
1502{
1503 return (pChipcHw->
1504 PhaseAlignStatus & chipcHw_REG_DDR_PHASE_STATUS_MASK) >>
1505 chipcHw_REG_DDR_PHASE_STATUS_SHIFT;
1506}
1507
1508/****************************************************************************/
1509/**
1510* @brief Get VPM phase aligned status done by HW
1511*
1512*/
1513/****************************************************************************/
1514static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void)
1515{
1516 return (pChipcHw->
1517 PhaseAlignStatus & chipcHw_REG_VPM_PHASE_STATUS_MASK) >>
1518 chipcHw_REG_VPM_PHASE_STATUS_SHIFT;
1519}
1520
1521/****************************************************************************/
1522/**
1523* @brief Get DDR phase control value
1524*
1525*/
1526/****************************************************************************/
1527static inline uint32_t chipcHw_getDdrPhaseControl(void)
1528{
1529 return (pChipcHw->
1530 PhaseAlignStatus & chipcHw_REG_DDR_PHASE_CTRL_MASK) >>
1531 chipcHw_REG_DDR_PHASE_CTRL_SHIFT;
1532}
1533
1534/****************************************************************************/
1535/**
1536* @brief Get VPM phase control value
1537*
1538*/
1539/****************************************************************************/
1540static inline uint32_t chipcHw_getVpmPhaseControl(void)
1541{
1542 return (pChipcHw->
1543 PhaseAlignStatus & chipcHw_REG_VPM_PHASE_CTRL_MASK) >>
1544 chipcHw_REG_VPM_PHASE_CTRL_SHIFT;
1545}
1546
1547/****************************************************************************/
1548/**
1549* @brief DDR phase alignment timeout count
1550*
1551* @note If HW fails to perform the phase alignment, it will trigger
1552* a DDR phase alignment timeout interrupt.
1553*/
1554/****************************************************************************/
1555static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle)
1556{
1557 REG_LOCAL_IRQ_SAVE;
1558 pChipcHw->DDRPhaseCtrl2 &=
1559 ~(chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK <<
1560 chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT);
1561 pChipcHw->DDRPhaseCtrl2 |=
1562 (busCycle & chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK) <<
1563 chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT;
1564 REG_LOCAL_IRQ_RESTORE;
1565}
1566
1567/****************************************************************************/
1568/**
1569* @brief VPM phase alignment timeout count
1570*
1571* @note If HW fails to perform the phase alignment, it will trigger
1572* a VPM phase alignment timeout interrupt.
1573*/
1574/****************************************************************************/
1575static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle)
1576{
1577 REG_LOCAL_IRQ_SAVE;
1578 pChipcHw->VPMPhaseCtrl2 &=
1579 ~(chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK <<
1580 chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT);
1581 pChipcHw->VPMPhaseCtrl2 |=
1582 (busCycle & chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK) <<
1583 chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT;
1584 REG_LOCAL_IRQ_RESTORE;
1585}
1586
1587/****************************************************************************/
1588/**
1589* @brief Clear DDR phase alignment timeout interrupt
1590*
1591*/
1592/****************************************************************************/
1593static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void)
1594{
1595 REG_LOCAL_IRQ_SAVE;
1596 /* Clear timeout interrupt service bit */
1597 pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_INTR_SERVICED;
1598 pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_INTR_SERVICED;
1599 REG_LOCAL_IRQ_RESTORE;
1600}
1601
1602/****************************************************************************/
1603/**
1604* @brief Clear VPM phase alignment timeout interrupt
1605*
1606*/
1607/****************************************************************************/
1608static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void)
1609{
1610 REG_LOCAL_IRQ_SAVE;
1611 /* Clear timeout interrupt service bit */
1612 pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_INTR_SERVICED;
1613 pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_INTR_SERVICED;
1614 REG_LOCAL_IRQ_RESTORE;
1615}
1616
1617/****************************************************************************/
1618/**
1619* @brief DDR phase alignment timeout interrupt enable
1620*
1621*/
1622/****************************************************************************/
1623static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void)
1624{
1625 REG_LOCAL_IRQ_SAVE;
1626 chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(); /* Recommended */
1627 /* Enable timeout interrupt */
1628 pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE;
1629 REG_LOCAL_IRQ_RESTORE;
1630}
1631
1632/****************************************************************************/
1633/**
1634* @brief VPM phase alignment timeout interrupt enable
1635*
1636*/
1637/****************************************************************************/
1638static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void)
1639{
1640 REG_LOCAL_IRQ_SAVE;
1641 chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(); /* Recommended */
1642 /* Enable timeout interrupt */
1643 pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE;
1644 REG_LOCAL_IRQ_RESTORE;
1645}
1646
1647/****************************************************************************/
1648/**
1649* @brief DDR phase alignment timeout interrupt disable
1650*
1651*/
1652/****************************************************************************/
1653static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void)
1654{
1655 REG_LOCAL_IRQ_SAVE;
1656 pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE;
1657 REG_LOCAL_IRQ_RESTORE;
1658}
1659
1660/****************************************************************************/
1661/**
1662* @brief VPM phase alignment timeout interrupt disable
1663*
1664*/
1665/****************************************************************************/
1666static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void)
1667{
1668 REG_LOCAL_IRQ_SAVE;
1669 pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE;
1670 REG_LOCAL_IRQ_RESTORE;
1671}
1672
1673#endif /* CHIPC_INLINE_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
new file mode 100644
index 000000000000..b162448f613c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
@@ -0,0 +1,530 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file chipcHw_reg.h
18*
19* @brief Definitions for low level chip control registers
20*
21*/
22/****************************************************************************/
23#ifndef CHIPCHW_REG_H
24#define CHIPCHW_REG_H
25
26#include <mach/csp/mm_io.h>
27#include <csp/reg.h>
28#include <mach/csp/ddrcReg.h>
29
30#define chipcHw_BASE_ADDRESS MM_IO_BASE_CHIPC
31
32typedef struct {
33 uint32_t ChipId; /* Chip ID */
34 uint32_t DDRClock; /* PLL1 Channel 1 for DDR clock */
35 uint32_t ARMClock; /* PLL1 Channel 2 for ARM clock */
36 uint32_t ESWClock; /* PLL1 Channel 3 for ESW system clock */
37 uint32_t VPMClock; /* PLL1 Channel 4 for VPM clock */
38 uint32_t ESW125Clock; /* PLL1 Channel 5 for ESW 125MHz clock */
39 uint32_t UARTClock; /* PLL1 Channel 6 for UART clock */
40 uint32_t SDIO0Clock; /* PLL1 Channel 7 for SDIO 0 clock */
41 uint32_t SDIO1Clock; /* PLL1 Channel 8 for SDIO 1 clock */
42 uint32_t SPIClock; /* PLL1 Channel 9 for SPI master Clock */
43 uint32_t ETMClock; /* PLL1 Channel 10 for ARM ETM Clock */
44
45 uint32_t ACLKClock; /* ACLK Clock (Divider) */
46 uint32_t OTPClock; /* OTP Clock (Divider) */
47 uint32_t I2CClock; /* I2C Clock (CK_13m) (Divider) */
48 uint32_t I2S0Clock; /* I2S0 Clock (Divider) */
49 uint32_t RTBUSClock; /* RTBUS (DDR PHY Config.) Clock (Divider) */
50 uint32_t pad1;
51 uint32_t APM100Clock; /* APM 100MHz CLK Clock (Divider) */
52 uint32_t TSCClock; /* TSC Clock (Divider) */
53 uint32_t LEDClock; /* LED Clock (Divider) */
54
55 uint32_t USBClock; /* PLL2 Channel 1 for USB clock */
56 uint32_t LCDClock; /* PLL2 Channel 2 for LCD clock */
57 uint32_t APMClock; /* PLL2 Channel 3 for APM 200 MHz clock */
58
59 uint32_t BusIntfClock; /* Bus interface clock */
60
61 uint32_t PLLStatus; /* PLL status register (PLL1) */
62 uint32_t PLLConfig; /* PLL configuration register (PLL1) */
63 uint32_t PLLPreDivider; /* PLL pre-divider control register (PLL1) */
64 uint32_t PLLDivider; /* PLL divider control register (PLL1) */
65 uint32_t PLLControl1; /* PLL analog control register #1 (PLL1) */
66 uint32_t PLLControl2; /* PLL analog control register #2 (PLL1) */
67
68 uint32_t I2S1Clock; /* I2S1 Clock */
69 uint32_t AudioEnable; /* Enable/ disable audio channel */
70 uint32_t SoftReset1; /* Reset blocks */
71 uint32_t SoftReset2; /* Reset blocks */
72 uint32_t Spare1; /* Phase align interrupts */
73 uint32_t Sticky; /* Sticky bits */
74 uint32_t MiscCtrl; /* Misc. control */
75 uint32_t pad3[3];
76
77 uint32_t PLLStatus2; /* PLL status register (PLL2) */
78 uint32_t PLLConfig2; /* PLL configuration register (PLL2) */
79 uint32_t PLLPreDivider2; /* PLL pre-divider control register (PLL2) */
80 uint32_t PLLDivider2; /* PLL divider control register (PLL2) */
81 uint32_t PLLControl12; /* PLL analog control register #1 (PLL2) */
82 uint32_t PLLControl22; /* PLL analog control register #2 (PLL2) */
83
84 uint32_t DDRPhaseCtrl1; /* DDR Clock Phase Alignment control1 */
85 uint32_t VPMPhaseCtrl1; /* VPM Clock Phase Alignment control1 */
86 uint32_t PhaseAlignStatus; /* DDR/VPM Clock Phase Alignment Status */
87 uint32_t PhaseCtrlStatus; /* DDR/VPM Clock HW DDR/VPM ph_ctrl and load_ch Status */
88 uint32_t DDRPhaseCtrl2; /* DDR Clock Phase Alignment control2 */
89 uint32_t VPMPhaseCtrl2; /* VPM Clock Phase Alignment control2 */
90 uint32_t pad4[9];
91
92 uint32_t SoftOTP1; /* Software OTP control */
93 uint32_t SoftOTP2; /* Software OTP control */
94 uint32_t SoftStraps; /* Software strap */
95 uint32_t PinStraps; /* Pin Straps */
96 uint32_t DiffOscCtrl; /* Diff oscillator control */
97 uint32_t DiagsCtrl; /* Diagnostic control */
98 uint32_t DiagsOutputCtrl; /* Diagnostic output enable */
99 uint32_t DiagsReadBackCtrl; /* Diagnostic read back control */
100
101 uint32_t LcdPifMode; /* LCD/PIF Pin Sharing MUX Mode */
102
103 uint32_t GpioMux_0_7; /* Pin Sharing MUX0 Control */
104 uint32_t GpioMux_8_15; /* Pin Sharing MUX1 Control */
105 uint32_t GpioMux_16_23; /* Pin Sharing MUX2 Control */
106 uint32_t GpioMux_24_31; /* Pin Sharing MUX3 Control */
107 uint32_t GpioMux_32_39; /* Pin Sharing MUX4 Control */
108 uint32_t GpioMux_40_47; /* Pin Sharing MUX5 Control */
109 uint32_t GpioMux_48_55; /* Pin Sharing MUX6 Control */
110 uint32_t GpioMux_56_63; /* Pin Sharing MUX7 Control */
111
112 uint32_t GpioSR_0_7; /* Slew rate for GPIO 0 - 7 */
113 uint32_t GpioSR_8_15; /* Slew rate for GPIO 8 - 15 */
114 uint32_t GpioSR_16_23; /* Slew rate for GPIO 16 - 23 */
115 uint32_t GpioSR_24_31; /* Slew rate for GPIO 24 - 31 */
116 uint32_t GpioSR_32_39; /* Slew rate for GPIO 32 - 39 */
117 uint32_t GpioSR_40_47; /* Slew rate for GPIO 40 - 47 */
118 uint32_t GpioSR_48_55; /* Slew rate for GPIO 48 - 55 */
119 uint32_t GpioSR_56_63; /* Slew rate for GPIO 56 - 63 */
120 uint32_t MiscSR_0_7; /* Slew rate for MISC 0 - 7 */
121 uint32_t MiscSR_8_15; /* Slew rate for MISC 8 - 15 */
122
123 uint32_t GpioPull_0_15; /* Pull up registers for GPIO 0 - 15 */
124 uint32_t GpioPull_16_31; /* Pull up registers for GPIO 16 - 31 */
125 uint32_t GpioPull_32_47; /* Pull up registers for GPIO 32 - 47 */
126 uint32_t GpioPull_48_63; /* Pull up registers for GPIO 48 - 63 */
127 uint32_t MiscPull_0_15; /* Pull up registers for MISC 0 - 15 */
128
129 uint32_t GpioInput_0_31; /* Input type for GPIO 0 - 31 */
130 uint32_t GpioInput_32_63; /* Input type for GPIO 32 - 63 */
131 uint32_t MiscInput_0_15; /* Input type for MISC 0 - 16 */
132} chipcHw_REG_t;
133
134#define pChipcHw ((volatile chipcHw_REG_t *) chipcHw_BASE_ADDRESS)
135#define pChipcPhysical ((volatile chipcHw_REG_t *) MM_ADDR_IO_CHIPC)
136
137#define chipcHw_REG_CHIPID_BASE_MASK 0xFFFFF000
138#define chipcHw_REG_CHIPID_BASE_SHIFT 12
139#define chipcHw_REG_CHIPID_REV_MASK 0x00000FFF
140#define chipcHw_REG_REV_A0 0xA00
141#define chipcHw_REG_REV_B0 0x0B0
142
143#define chipcHw_REG_PLL_STATUS_CONTROL_ENABLE 0x80000000 /* Allow controlling PLL registers */
144#define chipcHw_REG_PLL_STATUS_LOCKED 0x00000001 /* PLL is settled */
145#define chipcHw_REG_PLL_CONFIG_D_RESET 0x00000008 /* Digital reset */
146#define chipcHw_REG_PLL_CONFIG_A_RESET 0x00000004 /* Analog reset */
147#define chipcHw_REG_PLL_CONFIG_BYPASS_ENABLE 0x00000020 /* Bypass enable */
148#define chipcHw_REG_PLL_CONFIG_OUTPUT_ENABLE 0x00000010 /* Output enable */
149#define chipcHw_REG_PLL_CONFIG_POWER_DOWN 0x00000001 /* Power down */
150#define chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ 1600000000 /* 1.6GHz VCO split frequency */
151#define chipcHw_REG_PLL_CONFIG_VCO_800_1600 0x00000000 /* VCO range 800-1600 MHz */
152#define chipcHw_REG_PLL_CONFIG_VCO_1601_3200 0x00000080 /* VCO range 1601-3200 MHz */
153#define chipcHw_REG_PLL_CONFIG_TEST_ENABLE 0x00010000 /* PLL test output enable */
154#define chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK 0x003E0000 /* Mask to set test values */
155#define chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT 17
156
157#define chipcHw_REG_PLL_CLOCK_PHASE_COMP 0x00800000 /* Phase comparator output */
158#define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK 0x00300000 /* Clock to bus ratio mask */
159#define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT 20 /* Number of bits to be shifted */
160#define chipcHw_REG_PLL_CLOCK_POWER_DOWN 0x00080000 /* PLL channel power down */
161#define chipcHw_REG_PLL_CLOCK_SOURCE_GPIO 0x00040000 /* Use GPIO as source */
162#define chipcHw_REG_PLL_CLOCK_BYPASS_SELECT 0x00020000 /* Select bypass clock */
163#define chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE 0x00010000 /* Clock gated ON */
164#define chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE 0x00008000 /* Clock phase update enable */
165#define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT 8 /* Number of bits to be shifted */
166#define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK 0x00003F00 /* Phase control mask */
167#define chipcHw_REG_PLL_CLOCK_MDIV_MASK 0x000000FF /* Clock post divider mask
168
169 00000000 = divide-by-256
170 00000001 = divide-by-1
171 00000010 = divide-by-2
172 00000011 = divide-by-3
173 00000100 = divide-by-4
174 00000101 = divide-by-5
175 00000110 = divide-by-6
176 .
177 .
178 11111011 = divide-by-251
179 11111100 = divide-by-252
180 11111101 = divide-by-253
181 11111110 = divide-by-254
182 */
183
184#define chipcHw_REG_DIV_CLOCK_SOURCE_OTHER 0x00040000 /* NON-PLL clock source select */
185#define chipcHw_REG_DIV_CLOCK_BYPASS_SELECT 0x00020000 /* NON-PLL clock bypass enable */
186#define chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE 0x00010000 /* NON-PLL clock output enable */
187#define chipcHw_REG_DIV_CLOCK_DIV_MASK 0x000000FF /* NON-PLL clock post-divide mask */
188#define chipcHw_REG_DIV_CLOCK_DIV_256 0x00000000 /* NON-PLL clock post-divide by 256 */
189
190#define chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT 0
191#define chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT 4
192#define chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT 8
193#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK 0x0001FF00
194#define chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN 0x02000000
195#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK 0x00700000 /* Divider mask */
196#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER 0x00000000 /* Integer-N Mode */
197#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_UNIT 0x00100000 /* MASH Sigma-Delta Modulator Unit Mode */
198#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_UNIT 0x00200000 /* MFB Sigma-Delta Modulator Unit Mode */
199#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 0x00300000 /* MASH Sigma-Delta Modulator 1/8 Mode */
200#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_1_8 0x00400000 /* MFB Sigma-Delta Modulator 1/8 Mode */
201
202#define chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vco) ((vco) / chipcHw_XTAL_FREQ_Hz)
203#define chipcHw_REG_PLL_PREDIVIDER_P1 1
204#define chipcHw_REG_PLL_PREDIVIDER_P2 1
205
206#define chipcHw_REG_PLL_DIVIDER_M1DIV 0x03000000
207#define chipcHw_REG_PLL_DIVIDER_FRAC 0x00FFFFFF /* Fractional divider */
208
209#define chipcHw_REG_PLL_DIVIDER_NDIV_f_SS (0x00FFFFFF) /* To attain spread with max frequency */
210
211#define chipcHw_REG_PLL_DIVIDER_NDIV_f 0 /* ndiv_frac = chipcHw_REG_PLL_DIVIDER_NDIV_f /
212 chipcHw_REG_PLL_DIVIDER_FRAC
213 = 0, when SS is disable
214 */
215
216#define chipcHw_REG_PLL_DIVIDER_MDIV(vco, Hz) ((chipcHw_divide((vco), (Hz)) > 255) ? 0 : chipcHw_divide((vco), (Hz)))
217
218#define chipcHw_REG_ACLKClock_CLK_DIV_MASK 0x3
219
220/* System booting strap options */
221#define chipcHw_STRAPS_SOFT_OVERRIDE 0x00000001 /* Software Strap Override */
222
223#define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8 0x00000000 /* 8 bit NAND FLASH Boot */
224#define chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16 0x00000002 /* 16 bit NOR FLASH Boot */
225#define chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH 0x00000004 /* Serial FLASH Boot */
226#define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16 0x00000006 /* 16 bit NAND FLASH Boot */
227#define chipcHw_STRAPS_BOOT_DEVICE_UART 0x00000008 /* UART Boot */
228#define chipcHw_STRAPS_BOOT_DEVICE_MASK 0x0000000E /* Mask */
229
230/* System boot option */
231#define chipcHw_STRAPS_BOOT_OPTION_BROM 0x00000000 /* Boot from Boot ROM */
232#define chipcHw_STRAPS_BOOT_OPTION_ARAM 0x00000020 /* Boot from ARAM */
233#define chipcHw_STRAPS_BOOT_OPTION_NOR 0x00000030 /* Boot from NOR flash */
234
235/* NAND Flash page size strap options */
236#define chipcHw_STRAPS_NAND_PAGESIZE_512 0x00000000 /* NAND FLASH page size of 512 bytes */
237#define chipcHw_STRAPS_NAND_PAGESIZE_2048 0x00000040 /* NAND FLASH page size of 2048 bytes */
238#define chipcHw_STRAPS_NAND_PAGESIZE_4096 0x00000080 /* NAND FLASH page size of 4096 bytes */
239#define chipcHw_STRAPS_NAND_PAGESIZE_EXT 0x000000C0 /* NAND FLASH page of extened size */
240#define chipcHw_STRAPS_NAND_PAGESIZE_MASK 0x000000C0 /* Mask */
241
242#define chipcHw_STRAPS_NAND_EXTRA_CYCLE 0x00000400 /* NAND FLASH address cycle configuration */
243#define chipcHw_STRAPS_REBOOT_TO_UART 0x00000800 /* Reboot to UART on error */
244
245/* Secure boot mode strap options */
246#define chipcHw_STRAPS_BOOT_MODE_NORMAL 0x00000000 /* Normal Boot */
247#define chipcHw_STRAPS_BOOT_MODE_DBG_SW 0x00000100 /* Software debugging Boot */
248#define chipcHw_STRAPS_BOOT_MODE_DBG_BOOT 0x00000200 /* Boot rom debugging Boot */
249#define chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET 0x00000300 /* Normal Boot (Quiet BootRom) */
250#define chipcHw_STRAPS_BOOT_MODE_MASK 0x00000300 /* Mask */
251
252/* Slave Mode straps */
253#define chipcHw_STRAPS_I2CS 0x02000000 /* I2C Slave */
254#define chipcHw_STRAPS_SPIS 0x01000000 /* SPI Slave */
255
256/* Strap pin options */
257#define chipcHw_REG_SW_STRAPS ((pChipcHw->PinStraps & 0x0000FC00) >> 10)
258
259/* PIF/LCD pin sharing defines */
260#define chipcHw_REG_LCD_PIN_ENABLE 0x00000001 /* LCD Controller is used and the pins have LCD functions */
261#define chipcHw_REG_PIF_PIN_ENABLE 0x00000002 /* LCD pins are used to perform PIF functions */
262
263#define chipcHw_GPIO_COUNT 61 /* Number of GPIO pin accessible thorugh CHIPC */
264
265/* NOTE: Any changes to these constants will require a corresponding change to chipcHw_str.c */
266#define chipcHw_REG_GPIO_MUX_KEYPAD 0x00000001 /* GPIO mux for Keypad */
267#define chipcHw_REG_GPIO_MUX_I2CH 0x00000002 /* GPIO mux for I2CH */
268#define chipcHw_REG_GPIO_MUX_SPI 0x00000003 /* GPIO mux for SPI */
269#define chipcHw_REG_GPIO_MUX_UART 0x00000004 /* GPIO mux for UART */
270#define chipcHw_REG_GPIO_MUX_LEDMTXP 0x00000005 /* GPIO mux for LEDMTXP */
271#define chipcHw_REG_GPIO_MUX_LEDMTXS 0x00000006 /* GPIO mux for LEDMTXS */
272#define chipcHw_REG_GPIO_MUX_SDIO0 0x00000007 /* GPIO mux for SDIO0 */
273#define chipcHw_REG_GPIO_MUX_SDIO1 0x00000008 /* GPIO mux for SDIO1 */
274#define chipcHw_REG_GPIO_MUX_PCM 0x00000009 /* GPIO mux for PCM */
275#define chipcHw_REG_GPIO_MUX_I2S 0x0000000A /* GPIO mux for I2S */
276#define chipcHw_REG_GPIO_MUX_ETM 0x0000000B /* GPIO mux for ETM */
277#define chipcHw_REG_GPIO_MUX_DEBUG 0x0000000C /* GPIO mux for DEBUG */
278#define chipcHw_REG_GPIO_MUX_MISC 0x0000000D /* GPIO mux for MISC */
279#define chipcHw_REG_GPIO_MUX_GPIO 0x00000000 /* GPIO mux for GPIO */
280#define chipcHw_REG_GPIO_MUX(pin) (&pChipcHw->GpioMux_0_7 + ((pin) >> 3))
281#define chipcHw_REG_GPIO_MUX_POSITION(pin) (((pin) & 0x00000007) << 2)
282#define chipcHw_REG_GPIO_MUX_MASK 0x0000000F /* Mask */
283
284#define chipcHw_REG_SLEW_RATE_HIGH 0x00000000 /* High speed slew rate */
285#define chipcHw_REG_SLEW_RATE_NORMAL 0x00000008 /* Normal slew rate */
286 /* Pins beyond 42 are defined by skipping 8 bits within the register */
287#define chipcHw_REG_SLEW_RATE(pin) (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3)))
288#define chipcHw_REG_SLEW_RATE_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2))
289#define chipcHw_REG_SLEW_RATE_MASK 0x00000008 /* Mask */
290
291#define chipcHw_REG_CURRENT_STRENGTH_2mA 0x00000001 /* Current driving strength 2 milli ampere */
292#define chipcHw_REG_CURRENT_STRENGTH_4mA 0x00000002 /* Current driving strength 4 milli ampere */
293#define chipcHw_REG_CURRENT_STRENGTH_6mA 0x00000004 /* Current driving strength 6 milli ampere */
294#define chipcHw_REG_CURRENT_STRENGTH_8mA 0x00000005 /* Current driving strength 8 milli ampere */
295#define chipcHw_REG_CURRENT_STRENGTH_10mA 0x00000006 /* Current driving strength 10 milli ampere */
296#define chipcHw_REG_CURRENT_STRENGTH_12mA 0x00000007 /* Current driving strength 12 milli ampere */
297#define chipcHw_REG_CURRENT_MASK 0x00000007 /* Mask */
298 /* Pins beyond 42 are defined by skipping 8 bits */
299#define chipcHw_REG_CURRENT(pin) (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3)))
300#define chipcHw_REG_CURRENT_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2))
301
302#define chipcHw_REG_PULL_NONE 0x00000000 /* No pull up register */
303#define chipcHw_REG_PULL_UP 0x00000001 /* Pull up register enable */
304#define chipcHw_REG_PULL_DOWN 0x00000002 /* Pull down register enable */
305#define chipcHw_REG_PULLUP_MASK 0x00000003 /* Mask */
306 /* Pins beyond 42 are defined by skipping 4 bits */
307#define chipcHw_REG_PULLUP(pin) (((pin) > 42) ? (&pChipcHw->GpioPull_0_15 + (((pin) + 2) >> 4)) : (&pChipcHw->GpioPull_0_15 + ((pin) >> 4)))
308#define chipcHw_REG_PULLUP_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x0000000F) << 1) : (((pin) & 0x0000000F) << 1))
309
310#define chipcHw_REG_INPUTTYPE_CMOS 0x00000000 /* Normal CMOS logic */
311#define chipcHw_REG_INPUTTYPE_ST 0x00000001 /* High speed Schmitt Trigger */
312#define chipcHw_REG_INPUTTYPE_MASK 0x00000001 /* Mask */
313 /* Pins beyond 42 are defined by skipping 2 bits */
314#define chipcHw_REG_INPUTTYPE(pin) (((pin) > 42) ? (&pChipcHw->GpioInput_0_31 + (((pin) + 2) >> 5)) : (&pChipcHw->GpioInput_0_31 + ((pin) >> 5)))
315#define chipcHw_REG_INPUTTYPE_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x0000001F)) : (((pin) & 0x0000001F)))
316
317/* Device connected to the bus clock */
318#define chipcHw_REG_BUS_CLOCK_ARM 0x00000001 /* Bus interface clock for ARM */
319#define chipcHw_REG_BUS_CLOCK_VDEC 0x00000002 /* Bus interface clock for VDEC */
320#define chipcHw_REG_BUS_CLOCK_ARAM 0x00000004 /* Bus interface clock for ARAM */
321#define chipcHw_REG_BUS_CLOCK_HPM 0x00000008 /* Bus interface clock for HPM */
322#define chipcHw_REG_BUS_CLOCK_DDRC 0x00000010 /* Bus interface clock for DDRC */
323#define chipcHw_REG_BUS_CLOCK_DMAC0 0x00000020 /* Bus interface clock for DMAC0 */
324#define chipcHw_REG_BUS_CLOCK_DMAC1 0x00000040 /* Bus interface clock for DMAC1 */
325#define chipcHw_REG_BUS_CLOCK_NVI 0x00000080 /* Bus interface clock for NVI */
326#define chipcHw_REG_BUS_CLOCK_ESW 0x00000100 /* Bus interface clock for ESW */
327#define chipcHw_REG_BUS_CLOCK_GE 0x00000200 /* Bus interface clock for GE */
328#define chipcHw_REG_BUS_CLOCK_I2CH 0x00000400 /* Bus interface clock for I2CH */
329#define chipcHw_REG_BUS_CLOCK_I2S0 0x00000800 /* Bus interface clock for I2S0 */
330#define chipcHw_REG_BUS_CLOCK_I2S1 0x00001000 /* Bus interface clock for I2S1 */
331#define chipcHw_REG_BUS_CLOCK_VRAM 0x00002000 /* Bus interface clock for VRAM */
332#define chipcHw_REG_BUS_CLOCK_CLCD 0x00004000 /* Bus interface clock for CLCD */
333#define chipcHw_REG_BUS_CLOCK_LDK 0x00008000 /* Bus interface clock for LDK */
334#define chipcHw_REG_BUS_CLOCK_LED 0x00010000 /* Bus interface clock for LED */
335#define chipcHw_REG_BUS_CLOCK_OTP 0x00020000 /* Bus interface clock for OTP */
336#define chipcHw_REG_BUS_CLOCK_PIF 0x00040000 /* Bus interface clock for PIF */
337#define chipcHw_REG_BUS_CLOCK_SPU 0x00080000 /* Bus interface clock for SPU */
338#define chipcHw_REG_BUS_CLOCK_SDIO0 0x00100000 /* Bus interface clock for SDIO0 */
339#define chipcHw_REG_BUS_CLOCK_SDIO1 0x00200000 /* Bus interface clock for SDIO1 */
340#define chipcHw_REG_BUS_CLOCK_SPIH 0x00400000 /* Bus interface clock for SPIH */
341#define chipcHw_REG_BUS_CLOCK_SPIS 0x00800000 /* Bus interface clock for SPIS */
342#define chipcHw_REG_BUS_CLOCK_UART0 0x01000000 /* Bus interface clock for UART0 */
343#define chipcHw_REG_BUS_CLOCK_UART1 0x02000000 /* Bus interface clock for UART1 */
344#define chipcHw_REG_BUS_CLOCK_BBL 0x04000000 /* Bus interface clock for BBL */
345#define chipcHw_REG_BUS_CLOCK_I2CS 0x08000000 /* Bus interface clock for I2CS */
346#define chipcHw_REG_BUS_CLOCK_USBH 0x10000000 /* Bus interface clock for USB Host */
347#define chipcHw_REG_BUS_CLOCK_USBD 0x20000000 /* Bus interface clock for USB Device */
348#define chipcHw_REG_BUS_CLOCK_BROM 0x40000000 /* Bus interface clock for Boot ROM */
349#define chipcHw_REG_BUS_CLOCK_TSC 0x80000000 /* Bus interface clock for Touch screen */
350
351/* Software resets defines */
352#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD 0x0000000080000000ULL /* Reset Global VPM and hold */
353#define chipcHw_REG_SOFT_RESET_VPM_HOLD 0x0000000040000000ULL /* Reset VPM and hold */
354#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL 0x0000000020000000ULL /* Reset Global VPM */
355#define chipcHw_REG_SOFT_RESET_VPM 0x0000000010000000ULL /* Reset VPM */
356#define chipcHw_REG_SOFT_RESET_KEYPAD 0x0000000008000000ULL /* Reset Key pad */
357#define chipcHw_REG_SOFT_RESET_LED 0x0000000004000000ULL /* Reset LED */
358#define chipcHw_REG_SOFT_RESET_SPU 0x0000000002000000ULL /* Reset SPU */
359#define chipcHw_REG_SOFT_RESET_RNG 0x0000000001000000ULL /* Reset RNG */
360#define chipcHw_REG_SOFT_RESET_PKA 0x0000000000800000ULL /* Reset PKA */
361#define chipcHw_REG_SOFT_RESET_LCD 0x0000000000400000ULL /* Reset LCD */
362#define chipcHw_REG_SOFT_RESET_PIF 0x0000000000200000ULL /* Reset PIF */
363#define chipcHw_REG_SOFT_RESET_I2CS 0x0000000000100000ULL /* Reset I2C Slave */
364#define chipcHw_REG_SOFT_RESET_I2CH 0x0000000000080000ULL /* Reset I2C Host */
365#define chipcHw_REG_SOFT_RESET_SDIO1 0x0000000000040000ULL /* Reset SDIO 1 */
366#define chipcHw_REG_SOFT_RESET_SDIO0 0x0000000000020000ULL /* Reset SDIO 0 */
367#define chipcHw_REG_SOFT_RESET_BBL 0x0000000000010000ULL /* Reset BBL */
368#define chipcHw_REG_SOFT_RESET_I2S1 0x0000000000008000ULL /* Reset I2S1 */
369#define chipcHw_REG_SOFT_RESET_I2S0 0x0000000000004000ULL /* Reset I2S0 */
370#define chipcHw_REG_SOFT_RESET_SPIS 0x0000000000002000ULL /* Reset SPI Slave */
371#define chipcHw_REG_SOFT_RESET_SPIH 0x0000000000001000ULL /* Reset SPI Host */
372#define chipcHw_REG_SOFT_RESET_GPIO1 0x0000000000000800ULL /* Reset GPIO block 1 */
373#define chipcHw_REG_SOFT_RESET_GPIO0 0x0000000000000400ULL /* Reset GPIO block 0 */
374#define chipcHw_REG_SOFT_RESET_UART1 0x0000000000000200ULL /* Reset UART 1 */
375#define chipcHw_REG_SOFT_RESET_UART0 0x0000000000000100ULL /* Reset UART 0 */
376#define chipcHw_REG_SOFT_RESET_NVI 0x0000000000000080ULL /* Reset NVI */
377#define chipcHw_REG_SOFT_RESET_WDOG 0x0000000000000040ULL /* Reset Watch dog */
378#define chipcHw_REG_SOFT_RESET_TMR 0x0000000000000020ULL /* Reset Timer */
379#define chipcHw_REG_SOFT_RESET_ETM 0x0000000000000010ULL /* Reset ETM */
380#define chipcHw_REG_SOFT_RESET_ARM_HOLD 0x0000000000000008ULL /* Reset ARM and HOLD */
381#define chipcHw_REG_SOFT_RESET_ARM 0x0000000000000004ULL /* Reset ARM */
382#define chipcHw_REG_SOFT_RESET_CHIP_WARM 0x0000000000000002ULL /* Chip warm reset */
383#define chipcHw_REG_SOFT_RESET_CHIP_SOFT 0x0000000000000001ULL /* Chip soft reset */
384#define chipcHw_REG_SOFT_RESET_VDEC 0x0000100000000000ULL /* Video decoder */
385#define chipcHw_REG_SOFT_RESET_GE 0x0000080000000000ULL /* Graphics engine */
386#define chipcHw_REG_SOFT_RESET_OTP 0x0000040000000000ULL /* Reset OTP */
387#define chipcHw_REG_SOFT_RESET_USB2 0x0000020000000000ULL /* Reset USB2 */
388#define chipcHw_REG_SOFT_RESET_USB1 0x0000010000000000ULL /* Reset USB 1 */
389#define chipcHw_REG_SOFT_RESET_USB 0x0000008000000000ULL /* Reset USB 1 and USB2 soft reset */
390#define chipcHw_REG_SOFT_RESET_ESW 0x0000004000000000ULL /* Reset Ethernet switch */
391#define chipcHw_REG_SOFT_RESET_ESWCLK 0x0000002000000000ULL /* Reset Ethernet switch clock */
392#define chipcHw_REG_SOFT_RESET_DDRPHY 0x0000001000000000ULL /* Reset DDR Physical */
393#define chipcHw_REG_SOFT_RESET_DDR 0x0000000800000000ULL /* Reset DDR Controller */
394#define chipcHw_REG_SOFT_RESET_TSC 0x0000000400000000ULL /* Reset Touch screen */
395#define chipcHw_REG_SOFT_RESET_PCM 0x0000000200000000ULL /* Reset PCM device */
396#define chipcHw_REG_SOFT_RESET_APM 0x0000200100000000ULL /* Reset APM device */
397
398#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD 0x8000000000000000ULL /* Unhold Global VPM */
399#define chipcHw_REG_SOFT_RESET_VPM_UNHOLD 0x4000000000000000ULL /* Unhold VPM */
400#define chipcHw_REG_SOFT_RESET_ARM_UNHOLD 0x2000000000000000ULL /* Unhold ARM reset */
401#define chipcHw_REG_SOFT_RESET_UNHOLD_MASK 0xF000000000000000ULL /* Mask to handle unhold request */
402
403/* Audio channel control defines */
404#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_ALL 0x00000001 /* Enable all audio channel */
405#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_A 0x00000002 /* Enable channel A */
406#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_B 0x00000004 /* Enable channel B */
407#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_C 0x00000008 /* Enable channel C */
408#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_NTP_CLOCK 0x00000010 /* Enable NTP clock */
409#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM0_CLOCK 0x00000020 /* Enable PCM0 clock */
410#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM1_CLOCK 0x00000040 /* Enable PCM1 clock */
411#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_APM_CLOCK 0x00000080 /* Enable APM clock */
412
413/* Misc. chip control defines */
414#define chipcHw_REG_MISC_CTRL_GE_SEL 0x00040000 /* Select GE2/GE3 */
415#define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_ONCHIP 0x00000000 /* Use on chip clock for I2S1 */
416#define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_GPIO 0x00020000 /* Use external clock via GPIO pin 26 for I2S1 */
417#define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_ONCHIP 0x00000000 /* Use on chip clock for I2S0 */
418#define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_GPIO 0x00010000 /* Use external clock via GPIO pin 45 for I2S0 */
419#define chipcHw_REG_MISC_CTRL_ARM_CP15_DISABLE 0x00008000 /* Disable ARM CP15 bit */
420#define chipcHw_REG_MISC_CTRL_RTC_DISABLE 0x00000008 /* Disable RTC registers */
421#define chipcHw_REG_MISC_CTRL_BBRAM_DISABLE 0x00000004 /* Disable Battery Backed RAM */
422#define chipcHw_REG_MISC_CTRL_USB_MODE_HOST 0x00000002 /* Set USB as host */
423#define chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE 0xFFFFFFFD /* Set USB as device */
424#define chipcHw_REG_MISC_CTRL_USB_POWERON 0xFFFFFFFE /* Power up USB */
425#define chipcHw_REG_MISC_CTRL_USB_POWEROFF 0x00000001 /* Power down USB */
426
427/* OTP configuration defines */
428#define chipcHw_REG_OTP_SECURITY_OFF 0x0000020000000000ULL /* Security support is OFF */
429#define chipcHw_REG_OTP_SPU_SLOW 0x0000010000000000ULL /* Limited SPU throughput */
430#define chipcHw_REG_OTP_LCD_SPEED 0x0000000600000000ULL /* Set VPM speed one */
431#define chipcHw_REG_OTP_VPM_SPEED_1 0x0000000100000000ULL /* Set VPM speed one */
432#define chipcHw_REG_OTP_VPM_SPEED_0 0x0000000080000000ULL /* Set VPM speed zero */
433#define chipcHw_REG_OTP_AXI_SPEED 0x0000000060000000ULL /* Set maximum AXI bus speed */
434#define chipcHw_REG_OTP_APM_DISABLE 0x000000001F000000ULL /* Disable APM */
435#define chipcHw_REG_OTP_PIF_DISABLE 0x0000000000200000ULL /* Disable PIF */
436#define chipcHw_REG_OTP_VDEC_DISABLE 0x0000000000100000ULL /* Disable Video decoder */
437#define chipcHw_REG_OTP_BBL_DISABLE 0x0000000000080000ULL /* Disable RTC and BBRAM */
438#define chipcHw_REG_OTP_LED_DISABLE 0x0000000000040000ULL /* Disable LED */
439#define chipcHw_REG_OTP_GE_DISABLE 0x0000000000020000ULL /* Disable Graphics Engine */
440#define chipcHw_REG_OTP_LCD_DISABLE 0x0000000000010000ULL /* Disable LCD */
441#define chipcHw_REG_OTP_KEYPAD_DISABLE 0x0000000000008000ULL /* Disable keypad */
442#define chipcHw_REG_OTP_UART_DISABLE 0x0000000000004000ULL /* Disable UART */
443#define chipcHw_REG_OTP_SDIOH_DISABLE 0x0000000000003000ULL /* Disable SDIO host */
444#define chipcHw_REG_OTP_HSS_DISABLE 0x0000000000000C00ULL /* Disable HSS */
445#define chipcHw_REG_OTP_TSC_DISABLE 0x0000000000000200ULL /* Disable touch screen */
446#define chipcHw_REG_OTP_USB_DISABLE 0x0000000000000180ULL /* Disable USB */
447#define chipcHw_REG_OTP_SGMII_DISABLE 0x0000000000000060ULL /* Disable SGMII */
448#define chipcHw_REG_OTP_ETH_DISABLE 0x0000000000000018ULL /* Disable gigabit ethernet */
449#define chipcHw_REG_OTP_ETH_PHY_DISABLE 0x0000000000000006ULL /* Disable ethernet PHY */
450#define chipcHw_REG_OTP_VPM_DISABLE 0x0000000000000001ULL /* Disable VPM */
451
452/* Sticky bit defines */
453#define chipcHw_REG_STICKY_BOOT_DONE 0x00000001 /* Boot done */
454#define chipcHw_REG_STICKY_SOFT_RESET 0x00000002 /* ARM soft reset */
455#define chipcHw_REG_STICKY_GENERAL_1 0x00000004 /* General purpose bit 1 */
456#define chipcHw_REG_STICKY_GENERAL_2 0x00000008 /* General purpose bit 2 */
457#define chipcHw_REG_STICKY_GENERAL_3 0x00000010 /* General purpose bit 3 */
458#define chipcHw_REG_STICKY_GENERAL_4 0x00000020 /* General purpose bit 4 */
459#define chipcHw_REG_STICKY_GENERAL_5 0x00000040 /* General purpose bit 5 */
460#define chipcHw_REG_STICKY_POR_BROM 0x00000080 /* Special sticky bit for security - set in BROM to avoid other modes being entered */
461#define chipcHw_REG_STICKY_ARM_RESET 0x00000100 /* ARM reset */
462#define chipcHw_REG_STICKY_CHIP_SOFT_RESET 0x00000200 /* Chip soft reset */
463#define chipcHw_REG_STICKY_CHIP_WARM_RESET 0x00000400 /* Chip warm reset */
464#define chipcHw_REG_STICKY_WDOG_RESET 0x00000800 /* Watchdog reset */
465#define chipcHw_REG_STICKY_OTP_RESET 0x00001000 /* OTP reset */
466
467 /* HW phase alignment defines *//* Spare1 register definitions */
468#define chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE 0x80000000 /* Enable DDR phase align panic interrupt */
469#define chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE 0x40000000 /* Enable VPM phase align panic interrupt */
470#define chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE 0x00000002 /* Enable access to VPM using system BUS */
471#define chipcHw_REG_SPARE1_DDR_BUS_ACCESS_ENABLE 0x00000001 /* Enable access to DDR using system BUS */
472 /* DDRPhaseCtrl1 register definitions */
473#define chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE 0x80000000 /* Enable DDR SW phase alignment */
474#define chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE 0x40000000 /* Enable DDR HW phase alignment */
475#define chipcHw_REG_DDR_PHASE_VALUE_GE_MASK 0x0000007F /* DDR lower threshold for phase alignment */
476#define chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT 23
477#define chipcHw_REG_DDR_PHASE_VALUE_LE_MASK 0x0000007F /* DDR upper threshold for phase alignment */
478#define chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT 16
479#define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_MASK 0x0000FFFF /* BUS Cycle to wait to run next DDR phase alignment */
480#define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_SHIFT 0
481 /* VPMPhaseCtrl1 register definitions */
482#define chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE 0x80000000 /* Enable VPM SW phase alignment */
483#define chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE 0x40000000 /* Enable VPM HW phase alignment */
484#define chipcHw_REG_VPM_PHASE_VALUE_GE_MASK 0x0000007F /* VPM lower threshold for phase alignment */
485#define chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT 23
486#define chipcHw_REG_VPM_PHASE_VALUE_LE_MASK 0x0000007F /* VPM upper threshold for phase alignment */
487#define chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT 16
488#define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_MASK 0x0000FFFF /* BUS Cycle to wait to complete the VPM phase alignment */
489#define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_SHIFT 0
490 /* PhaseAlignStatus register definitions */
491#define chipcHw_REG_DDR_TIMEOUT_INTR_STATUS 0x80000000 /* DDR time out interrupt status */
492#define chipcHw_REG_DDR_PHASE_STATUS_MASK 0x0000007F /* DDR phase status value */
493#define chipcHw_REG_DDR_PHASE_STATUS_SHIFT 24
494#define chipcHw_REG_DDR_PHASE_ALIGNED 0x00800000 /* DDR Phase aligned status */
495#define chipcHw_REG_DDR_LOAD 0x00400000 /* Load DDR phase status */
496#define chipcHw_REG_DDR_PHASE_CTRL_MASK 0x0000003F /* DDR phase control value */
497#define chipcHw_REG_DDR_PHASE_CTRL_SHIFT 16
498#define chipcHw_REG_VPM_TIMEOUT_INTR_STATUS 0x80000000 /* VPM time out interrupt status */
499#define chipcHw_REG_VPM_PHASE_STATUS_MASK 0x0000007F /* VPM phase status value */
500#define chipcHw_REG_VPM_PHASE_STATUS_SHIFT 8
501#define chipcHw_REG_VPM_PHASE_ALIGNED 0x00000080 /* VPM Phase aligned status */
502#define chipcHw_REG_VPM_LOAD 0x00000040 /* Load VPM phase status */
503#define chipcHw_REG_VPM_PHASE_CTRL_MASK 0x0000003F /* VPM phase control value */
504#define chipcHw_REG_VPM_PHASE_CTRL_SHIFT 0
505 /* DDRPhaseCtrl2 register definitions */
506#define chipcHw_REG_DDR_INTR_SERVICED 0x02000000 /* Acknowledge that interrupt was serviced */
507#define chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE 0x01000000 /* Enable time out interrupt */
508#define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_MASK 0x0000000F /* Wait before toggling load_ch */
509#define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_SHIFT 20
510#define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_MASK 0x0000000F /* Total wait to settle ph_ctrl and load_ch */
511#define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_SHIFT 16
512#define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK 0x0000FFFF /* Time out value for DDR HW phase alignment */
513#define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT 0
514 /* VPMPhaseCtrl2 register definitions */
515#define chipcHw_REG_VPM_INTR_SELECT_MASK 0x00000003 /* Interrupt select */
516#define chipcHw_REG_VPM_INTR_SELECT_SHIFT 26
517#define chipcHw_REG_VPM_INTR_DISABLE 0x00000000
518#define chipcHw_REG_VPM_INTR_FAST (0x1 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
519#define chipcHw_REG_VPM_INTR_MEDIUM (0x2 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
520#define chipcHw_REG_VPM_INTR_SLOW (0x3 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
521#define chipcHw_REG_VPM_INTR_SERVICED 0x02000000 /* Acknowledge that interrupt was serviced */
522#define chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE 0x01000000 /* Enable time out interrupt */
523#define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_MASK 0x0000000F /* Wait before toggling load_ch */
524#define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_SHIFT 20
525#define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_MASK 0x0000000F /* Total wait cycle to settle ph_ctrl and load_ch */
526#define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_SHIFT 16
527#define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK 0x0000FFFF /* Time out value for VPM HW phase alignment */
528#define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT 0
529
530#endif /* CHIPCHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h
new file mode 100644
index 000000000000..f1b68e26fa6d
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h
@@ -0,0 +1,872 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file ddrcReg.h
18*
19* @brief Register definitions for BCMRING DDR2 Controller and PHY
20*
21*/
22/****************************************************************************/
23
24#ifndef DDRC_REG_H
25#define DDRC_REG_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/* ---- Include Files ---------------------------------------------------- */
32
33#include <csp/reg.h>
34#include <csp/stdint.h>
35
36#include <mach/csp/mm_io.h>
37
38/* ---- Public Constants and Types --------------------------------------- */
39
40/*********************************************************************/
41/* DDR2 Controller (ARM PL341) register definitions */
42/*********************************************************************/
43
44/* -------------------------------------------------------------------- */
45/* -------------------------------------------------------------------- */
46/* ARM PL341 DDR2 configuration registers, offset 0x000 */
47/* -------------------------------------------------------------------- */
48/* -------------------------------------------------------------------- */
49
50 typedef struct {
51 uint32_t memcStatus;
52 uint32_t memcCmd;
53 uint32_t directCmd;
54 uint32_t memoryCfg;
55 uint32_t refreshPrd;
56 uint32_t casLatency;
57 uint32_t writeLatency;
58 uint32_t tMrd;
59 uint32_t tRas;
60 uint32_t tRc;
61 uint32_t tRcd;
62 uint32_t tRfc;
63 uint32_t tRp;
64 uint32_t tRrd;
65 uint32_t tWr;
66 uint32_t tWtr;
67 uint32_t tXp;
68 uint32_t tXsr;
69 uint32_t tEsr;
70 uint32_t memoryCfg2;
71 uint32_t memoryCfg3;
72 uint32_t tFaw;
73 } ddrcReg_CTLR_MEMC_REG_t;
74
75#define ddrcReg_CTLR_MEMC_REG_OFFSET 0x0000
76#define ddrcReg_CTLR_MEMC_REGP ((volatile ddrcReg_CTLR_MEMC_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_MEMC_REG_OFFSET))
77
78/* ----------------------------------------------------- */
79
80#define ddrcReg_CTLR_MEMC_STATUS_BANKS_MASK (0x3 << 12)
81#define ddrcReg_CTLR_MEMC_STATUS_BANKS_4 (0x0 << 12)
82#define ddrcReg_CTLR_MEMC_STATUS_BANKS_8 (0x3 << 12)
83
84#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_MASK (0x3 << 10)
85#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_0 (0x0 << 10)
86#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_1 (0x1 << 10)
87#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_2 (0x2 << 10)
88#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_4 (0x3 << 10)
89
90#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_MASK (0x3 << 7)
91#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_1 (0x0 << 7)
92#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_2 (0x1 << 7)
93#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_3 (0x2 << 7)
94#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_4 (0x3 << 7)
95
96#define ddrcReg_CTLR_MEMC_STATUS_TYPE_MASK (0x7 << 4)
97#define ddrcReg_CTLR_MEMC_STATUS_TYPE_DDR2 (0x5 << 4)
98
99#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_MASK (0x3 << 2)
100#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_16 (0x0 << 2)
101#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_32 (0x1 << 2)
102#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_64 (0x2 << 2)
103#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_128 (0x3 << 2)
104
105#define ddrcReg_CTLR_MEMC_STATUS_STATE_MASK (0x3 << 0)
106#define ddrcReg_CTLR_MEMC_STATUS_STATE_CONFIG (0x0 << 0)
107#define ddrcReg_CTLR_MEMC_STATUS_STATE_READY (0x1 << 0)
108#define ddrcReg_CTLR_MEMC_STATUS_STATE_PAUSED (0x2 << 0)
109#define ddrcReg_CTLR_MEMC_STATUS_STATE_LOWPWR (0x3 << 0)
110
111/* ----------------------------------------------------- */
112
113#define ddrcReg_CTLR_MEMC_CMD_MASK (0x7 << 0)
114#define ddrcReg_CTLR_MEMC_CMD_GO (0x0 << 0)
115#define ddrcReg_CTLR_MEMC_CMD_SLEEP (0x1 << 0)
116#define ddrcReg_CTLR_MEMC_CMD_WAKEUP (0x2 << 0)
117#define ddrcReg_CTLR_MEMC_CMD_PAUSE (0x3 << 0)
118#define ddrcReg_CTLR_MEMC_CMD_CONFIGURE (0x4 << 0)
119#define ddrcReg_CTLR_MEMC_CMD_ACTIVE_PAUSE (0x7 << 0)
120
121/* ----------------------------------------------------- */
122
123#define ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT 20
124#define ddrcReg_CTLR_DIRECT_CMD_CHIP_MASK (0x3 << ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT)
125
126#define ddrcReg_CTLR_DIRECT_CMD_TYPE_PRECHARGEALL (0x0 << 18)
127#define ddrcReg_CTLR_DIRECT_CMD_TYPE_AUTOREFRESH (0x1 << 18)
128#define ddrcReg_CTLR_DIRECT_CMD_TYPE_MODEREG (0x2 << 18)
129#define ddrcReg_CTLR_DIRECT_CMD_TYPE_NOP (0x3 << 18)
130
131#define ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT 16
132#define ddrcReg_CTLR_DIRECT_CMD_BANK_MASK (0x3 << ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT)
133
134#define ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT 0
135#define ddrcReg_CTLR_DIRECT_CMD_ADDR_MASK (0x1ffff << ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT)
136
137/* ----------------------------------------------------- */
138
139#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_MASK (0x3 << 21)
140#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_1 (0x0 << 21)
141#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_2 (0x1 << 21)
142#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_3 (0x2 << 21)
143#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_4 (0x3 << 21)
144
145#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_MASK (0x7 << 18)
146#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_3_0 (0x0 << 18)
147#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_4_1 (0x1 << 18)
148#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_5_2 (0x2 << 18)
149#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_6_3 (0x3 << 18)
150#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_7_4 (0x4 << 18)
151#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_8_5 (0x5 << 18)
152#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_9_6 (0x6 << 18)
153#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_10_7 (0x7 << 18)
154
155#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_MASK (0x7 << 15)
156#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_4 (0x2 << 15)
157#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_8 (0x3 << 15) /* @note Not supported in PL341 */
158
159#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_ENABLE (0x1 << 13)
160
161#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT 7
162#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_MASK (0x3f << ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT)
163
164#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_MASK (0x7 << 3)
165#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_11 (0x0 << 3)
166#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_12 (0x1 << 3)
167#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_13 (0x2 << 3)
168#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_14 (0x3 << 3)
169#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_15 (0x4 << 3)
170#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_16 (0x5 << 3)
171
172#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_MASK (0x7 << 0)
173#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_9 (0x1 << 0)
174#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_10 (0x2 << 0)
175#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_11 (0x3 << 0)
176
177/* ----------------------------------------------------- */
178
179#define ddrcReg_CTLR_REFRESH_PRD_SHIFT 0
180#define ddrcReg_CTLR_REFRESH_PRD_MASK (0x7fff << ddrcReg_CTLR_REFRESH_PRD_SHIFT)
181
182/* ----------------------------------------------------- */
183
184#define ddrcReg_CTLR_CAS_LATENCY_SHIFT 1
185#define ddrcReg_CTLR_CAS_LATENCY_MASK (0x7 << ddrcReg_CTLR_CAS_LATENCY_SHIFT)
186
187/* ----------------------------------------------------- */
188
189#define ddrcReg_CTLR_WRITE_LATENCY_SHIFT 0
190#define ddrcReg_CTLR_WRITE_LATENCY_MASK (0x7 << ddrcReg_CTLR_WRITE_LATENCY_SHIFT)
191
192/* ----------------------------------------------------- */
193
194#define ddrcReg_CTLR_T_MRD_SHIFT 0
195#define ddrcReg_CTLR_T_MRD_MASK (0x7f << ddrcReg_CTLR_T_MRD_SHIFT)
196
197/* ----------------------------------------------------- */
198
199#define ddrcReg_CTLR_T_RAS_SHIFT 0
200#define ddrcReg_CTLR_T_RAS_MASK (0x1f << ddrcReg_CTLR_T_RAS_SHIFT)
201
202/* ----------------------------------------------------- */
203
204#define ddrcReg_CTLR_T_RC_SHIFT 0
205#define ddrcReg_CTLR_T_RC_MASK (0x1f << ddrcReg_CTLR_T_RC_SHIFT)
206
207/* ----------------------------------------------------- */
208
209#define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT 8
210#define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_MASK (0x7 << ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT)
211
212#define ddrcReg_CTLR_T_RCD_SHIFT 0
213#define ddrcReg_CTLR_T_RCD_MASK (0x7 << ddrcReg_CTLR_T_RCD_SHIFT)
214
215/* ----------------------------------------------------- */
216
217#define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT 8
218#define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_MASK (0x7f << ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT)
219
220#define ddrcReg_CTLR_T_RFC_SHIFT 0
221#define ddrcReg_CTLR_T_RFC_MASK (0x7f << ddrcReg_CTLR_T_RFC_SHIFT)
222
223/* ----------------------------------------------------- */
224
225#define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT 8
226#define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_MASK (0x7 << ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT)
227
228#define ddrcReg_CTLR_T_RP_SHIFT 0
229#define ddrcReg_CTLR_T_RP_MASK (0xf << ddrcReg_CTLR_T_RP_SHIFT)
230
231/* ----------------------------------------------------- */
232
233#define ddrcReg_CTLR_T_RRD_SHIFT 0
234#define ddrcReg_CTLR_T_RRD_MASK (0xf << ddrcReg_CTLR_T_RRD_SHIFT)
235
236/* ----------------------------------------------------- */
237
238#define ddrcReg_CTLR_T_WR_SHIFT 0
239#define ddrcReg_CTLR_T_WR_MASK (0x7 << ddrcReg_CTLR_T_WR_SHIFT)
240
241/* ----------------------------------------------------- */
242
243#define ddrcReg_CTLR_T_WTR_SHIFT 0
244#define ddrcReg_CTLR_T_WTR_MASK (0x7 << ddrcReg_CTLR_T_WTR_SHIFT)
245
246/* ----------------------------------------------------- */
247
248#define ddrcReg_CTLR_T_XP_SHIFT 0
249#define ddrcReg_CTLR_T_XP_MASK (0xff << ddrcReg_CTLR_T_XP_SHIFT)
250
251/* ----------------------------------------------------- */
252
253#define ddrcReg_CTLR_T_XSR_SHIFT 0
254#define ddrcReg_CTLR_T_XSR_MASK (0xff << ddrcReg_CTLR_T_XSR_SHIFT)
255
256/* ----------------------------------------------------- */
257
258#define ddrcReg_CTLR_T_ESR_SHIFT 0
259#define ddrcReg_CTLR_T_ESR_MASK (0xff << ddrcReg_CTLR_T_ESR_SHIFT)
260
261/* ----------------------------------------------------- */
262
263#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_MASK (0x3 << 6)
264#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_16BITS (0 << 6)
265#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_32BITS (1 << 6)
266#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_64BITS (2 << 6)
267
268#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_MASK (0x3 << 4)
269#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_2 (0 << 4)
270#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_3 (3 << 4)
271
272#define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_LOW (0 << 3)
273#define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_HIGH (1 << 3)
274
275#define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_LOW (0 << 2)
276#define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_HIGH (1 << 2)
277
278#define ddrcReg_CTLR_MEMORY_CFG2_CLK_MASK (0x3 << 0)
279#define ddrcReg_CTLR_MEMORY_CFG2_CLK_ASYNC (0 << 0)
280#define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_LE_M (1 << 0)
281#define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_GT_M (3 << 0)
282
283/* ----------------------------------------------------- */
284
285#define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT 0
286#define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_MASK (0x7 << ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT)
287
288/* ----------------------------------------------------- */
289
290#define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT 8
291#define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_MASK (0x1f << ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT)
292
293#define ddrcReg_CTLR_T_FAW_PERIOD_SHIFT 0
294#define ddrcReg_CTLR_T_FAW_PERIOD_MASK (0x1f << ddrcReg_CTLR_T_FAW_PERIOD_SHIFT)
295
296/* -------------------------------------------------------------------- */
297/* -------------------------------------------------------------------- */
298/* ARM PL341 AXI ID QOS configuration registers, offset 0x100 */
299/* -------------------------------------------------------------------- */
300/* -------------------------------------------------------------------- */
301
302#define ddrcReg_CTLR_QOS_CNT 16
303#define ddrcReg_CTLR_QOS_MAX (ddrcReg_CTLR_QOS_CNT - 1)
304
305 typedef struct {
306 uint32_t cfg[ddrcReg_CTLR_QOS_CNT];
307 } ddrcReg_CTLR_QOS_REG_t;
308
309#define ddrcReg_CTLR_QOS_REG_OFFSET 0x100
310#define ddrcReg_CTLR_QOS_REGP ((volatile ddrcReg_CTLR_QOS_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_QOS_REG_OFFSET))
311
312/* ----------------------------------------------------- */
313
314#define ddrcReg_CTLR_QOS_CFG_MAX_SHIFT 2
315#define ddrcReg_CTLR_QOS_CFG_MAX_MASK (0xff << ddrcReg_CTLR_QOS_CFG_MAX_SHIFT)
316
317#define ddrcReg_CTLR_QOS_CFG_MIN_SHIFT 1
318#define ddrcReg_CTLR_QOS_CFG_MIN_MASK (1 << ddrcReg_CTLR_QOS_CFG_MIN_SHIFT)
319
320#define ddrcReg_CTLR_QOS_CFG_ENABLE (1 << 0)
321
322/* -------------------------------------------------------------------- */
323/* -------------------------------------------------------------------- */
324/* ARM PL341 Memory chip configuration registers, offset 0x200 */
325/* -------------------------------------------------------------------- */
326/* -------------------------------------------------------------------- */
327
328#define ddrcReg_CTLR_CHIP_CNT 4
329#define ddrcReg_CTLR_CHIP_MAX (ddrcReg_CTLR_CHIP_CNT - 1)
330
331 typedef struct {
332 uint32_t cfg[ddrcReg_CTLR_CHIP_CNT];
333 } ddrcReg_CTLR_CHIP_REG_t;
334
335#define ddrcReg_CTLR_CHIP_REG_OFFSET 0x200
336#define ddrcReg_CTLR_CHIP_REGP ((volatile ddrcReg_CTLR_CHIP_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_CHIP_REG_OFFSET))
337
338/* ----------------------------------------------------- */
339
340#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_MASK (1 << 16)
341#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_ROW_BANK_COL (0 << 16)
342#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_BANK_ROW_COL (1 << 16)
343
344#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT 8
345#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_MASK (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT)
346
347#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT 0
348#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_MASK (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT)
349
350/* -------------------------------------------------------------------- */
351/* -------------------------------------------------------------------- */
352/* ARM PL341 User configuration registers, offset 0x300 */
353/* -------------------------------------------------------------------- */
354/* -------------------------------------------------------------------- */
355
356#define ddrcReg_CTLR_USER_OUTPUT_CNT 2
357
358 typedef struct {
359 uint32_t input;
360 uint32_t output[ddrcReg_CTLR_USER_OUTPUT_CNT];
361 uint32_t feature;
362 } ddrcReg_CTLR_USER_REG_t;
363
364#define ddrcReg_CTLR_USER_REG_OFFSET 0x300
365#define ddrcReg_CTLR_USER_REGP ((volatile ddrcReg_CTLR_USER_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_USER_REG_OFFSET))
366
367/* ----------------------------------------------------- */
368
369#define ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT 0
370#define ddrcReg_CTLR_USER_INPUT_STATUS_MASK (0xff << ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT)
371
372/* ----------------------------------------------------- */
373
374#define ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT 0
375#define ddrcReg_CTLR_USER_OUTPUT_CFG_MASK (0xff << ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT)
376
377#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT 1
378#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_MASK (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
379#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_BP134 (0 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
380#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301 (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
381#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301
382
383/* ----------------------------------------------------- */
384
385#define ddrcReg_CTLR_FEATURE_WRITE_BLOCK_DISABLE (1 << 2)
386#define ddrcReg_CTLR_FEATURE_EARLY_BURST_RSP_DISABLE (1 << 0)
387
388/*********************************************************************/
389/* Broadcom DDR23 PHY register definitions */
390/*********************************************************************/
391
392/* -------------------------------------------------------------------- */
393/* -------------------------------------------------------------------- */
394/* Broadcom DDR23 PHY Address and Control register definitions */
395/* -------------------------------------------------------------------- */
396/* -------------------------------------------------------------------- */
397
398 typedef struct {
399 uint32_t revision;
400 uint32_t pmCtl;
401 REG32_RSVD(0x0008, 0x0010);
402 uint32_t pllStatus;
403 uint32_t pllCfg;
404 uint32_t pllPreDiv;
405 uint32_t pllDiv;
406 uint32_t pllCtl1;
407 uint32_t pllCtl2;
408 uint32_t ssCtl;
409 uint32_t ssCfg;
410 uint32_t vdlStatic;
411 uint32_t vdlDynamic;
412 uint32_t padIdle;
413 uint32_t pvtComp;
414 uint32_t padDrive;
415 uint32_t clkRgltrCtl;
416 } ddrcReg_PHY_ADDR_CTL_REG_t;
417
418#define ddrcReg_PHY_ADDR_CTL_REG_OFFSET 0x0400
419#define ddrcReg_PHY_ADDR_CTL_REGP ((volatile ddrcReg_PHY_ADDR_CTL_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_ADDR_CTL_REG_OFFSET))
420
421/* @todo These SS definitions are duplicates of ones below */
422
423#define ddrcReg_PHY_ADDR_SS_CTRL_ENABLE 0x00000001
424#define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_MASK 0xFFFF0000
425#define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT 16
426#define ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK 10 /* Higher the value, lower the SS modulation frequency */
427#define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_MASK 0x0000FFFF
428#define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT 0
429
430/* ----------------------------------------------------- */
431
432#define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT 8
433#define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_MASK (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT)
434
435#define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT 0
436#define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_MASK (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT)
437
438/* ----------------------------------------------------- */
439
440#define ddrcReg_PHY_ADDR_CTL_CLK_PM_CTL_DDR_CLK_DISABLE (1 << 0)
441
442/* ----------------------------------------------------- */
443
444#define ddrcReg_PHY_ADDR_CTL_PLL_STATUS_LOCKED (1 << 0)
445
446/* ----------------------------------------------------- */
447
448#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_DIV2_CLK_RESET (1 << 31)
449
450#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT 17
451#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT)
452
453#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_ENABLE (1 << 16)
454
455#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT 12
456#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT)
457
458#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_VCO_RNG (1 << 7)
459#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CH1_PWRDWN (1 << 6)
460#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BYPASS_ENABLE (1 << 5)
461#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CLKOUT_ENABLE (1 << 4)
462#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_D_RESET (1 << 3)
463#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_A_RESET (1 << 2)
464#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_PWRDWN (1 << 0)
465
466/* ----------------------------------------------------- */
467
468#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_DITHER_MFB (1 << 26)
469#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_PWRDWN (1 << 25)
470
471#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT 20
472#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT)
473
474#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT 8
475#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_MASK (0x1ff << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT)
476
477#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT 4
478#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT)
479
480#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT 0
481#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT)
482
483/* ----------------------------------------------------- */
484
485#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT 24
486#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_MASK (0xff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT)
487
488#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT 0
489#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_MASK (0xffffff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT)
490
491/* ----------------------------------------------------- */
492
493#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT 30
494#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT)
495
496#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT 27
497#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT)
498
499#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT 24
500#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT)
501
502#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT 22
503#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT)
504
505#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LF_ORDER (0x1 << 21)
506
507#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT 19
508#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT)
509
510#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT 17
511#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT)
512
513#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT 15
514#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT)
515
516#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT 13
517#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT)
518
519#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT 10
520#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT)
521
522#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT 5
523#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT)
524
525#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT 0
526#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT)
527
528/* ----------------------------------------------------- */
529#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT 4
530#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT)
531
532#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT 2
533#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT)
534
535#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_LOWCUR_ENABLE (0x1 << 1)
536#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_BIASIN_ENABLE (0x1 << 0)
537
538/* ----------------------------------------------------- */
539
540#define ddrcReg_PHY_ADDR_CTL_PLL_SS_EN_ENABLE (0x1 << 0)
541
542/* ----------------------------------------------------- */
543
544#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT 16
545#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_MASK (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT)
546
547#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT 0
548#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_MASK (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT)
549
550/* ----------------------------------------------------- */
551
552#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FORCE (1 << 20)
553#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_ENABLE (1 << 16)
554
555#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT 12
556#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT)
557
558#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT 8
559#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT)
560
561#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT 0
562#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_MASK (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT)
563
564/* ----------------------------------------------------- */
565
566#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_ENABLE (1 << 16)
567
568#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT 12
569#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT)
570
571#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT 8
572#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT)
573
574#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT 0
575#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_MASK (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT)
576
577/* ----------------------------------------------------- */
578
579#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_ENABLE (1u << 31)
580#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_RXENB_DISABLE (1 << 8)
581#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_IDDQ_DISABLE (1 << 6)
582#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_REB_DISABLE (1 << 5)
583#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_OEB_DISABLE (1 << 4)
584#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_IDDQ_DISABLE (1 << 2)
585#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_REB_DISABLE (1 << 1)
586#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_OEB_DISABLE (1 << 0)
587
588/* ----------------------------------------------------- */
589
590#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_DONE (1 << 30)
591#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_DONE (1 << 29)
592#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_DONE (1 << 28)
593#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_AUTO_ENABLE (1 << 27)
594#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_ENABLE (1 << 26)
595#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_OVR_ENABLE (1 << 25)
596#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_OVR_ENABLE (1 << 24)
597
598#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT 20
599#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT)
600
601#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT 16
602#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT)
603
604#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT 12
605#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT)
606
607#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT 8
608#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT)
609
610#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT 4
611#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT)
612
613#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT 0
614#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT)
615
616/* ----------------------------------------------------- */
617
618#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_RT60B (1 << 4)
619#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SEL_SSTL18 (1 << 3)
620#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELTXDRV_CI (1 << 2)
621#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELRXDRV (1 << 1)
622#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SLEW (1 << 0)
623
624/* ----------------------------------------------------- */
625
626#define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_HALF (1 << 1)
627#define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_OFF (1 << 0)
628
629/* -------------------------------------------------------------------- */
630/* -------------------------------------------------------------------- */
631/* Broadcom DDR23 PHY Byte Lane register definitions */
632/* -------------------------------------------------------------------- */
633/* -------------------------------------------------------------------- */
634
635#define ddrcReg_PHY_BYTE_LANE_CNT 2
636#define ddrcReg_PHY_BYTE_LANE_MAX (ddrcReg_CTLR_BYTE_LANE_CNT - 1)
637
638#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT 8
639
640 typedef struct {
641 uint32_t revision;
642 uint32_t vdlCalibrate;
643 uint32_t vdlStatus;
644 REG32_RSVD(0x000c, 0x0010);
645 uint32_t vdlOverride[ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT];
646 uint32_t readCtl;
647 uint32_t readStatus;
648 uint32_t readClear;
649 uint32_t padIdleCtl;
650 uint32_t padDriveCtl;
651 uint32_t padClkCtl;
652 uint32_t writeCtl;
653 uint32_t clkRegCtl;
654 } ddrcReg_PHY_BYTE_LANE_REG_t;
655
656/* There are 2 instances of the byte Lane registers, one for each byte lane. */
657#define ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET 0x0500
658#define ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET 0x0600
659
660#define ddrcReg_PHY_BYTE_LANE_1_REGP ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET))
661#define ddrcReg_PHY_BYTE_LANE_2_REGP ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET))
662
663/* ----------------------------------------------------- */
664
665#define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT 8
666#define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_MASK (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT)
667
668#define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT 0
669#define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_MASK (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT)
670
671/* ----------------------------------------------------- */
672
673#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_2CYCLE (1 << 4)
674#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_1CYCLE (0 << 4)
675
676#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_TEST (1 << 3)
677#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ALWAYS (1 << 2)
678#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ONCE (1 << 1)
679#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_FAST (1 << 0)
680
681/* ----------------------------------------------------- */
682
683/* The byte lane VDL status calibTotal[9:0] is comprised of [9:4] step value, [3:2] fine fall */
684/* and [1:0] fine rise. Note that calibTotal[9:0] is located at bit 4 in the VDL status */
685/* register. The fine rise and fall are no longer used, so add some definitions for just */
686/* the step setting to simplify things. */
687
688#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT 8
689#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_MASK (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT)
690
691#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT 4
692#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_MASK (0x3ff << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT)
693
694#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_LOCK (1 << 1)
695#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_IDLE (1 << 0)
696
697/* ----------------------------------------------------- */
698
699#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_ENABLE (1 << 16)
700
701#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT 12
702#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT)
703
704#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT 8
705#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT)
706
707#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT 0
708#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_MASK (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT)
709
710#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_P 0
711#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_N 1
712#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_EN 2
713#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_WRITE_DQ_DQM 3
714#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_P 4
715#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_N 5
716#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_EN 6
717#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_WRITE_DQ_DQM 7
718
719/* ----------------------------------------------------- */
720
721#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT 8
722#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT)
723
724#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ENABLE (1 << 3)
725#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ADJUST (1 << 2)
726#define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ENABLE (1 << 1)
727#define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ADJUST (1 << 0)
728
729/* ----------------------------------------------------- */
730
731#define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT 0
732#define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_MASK (0xf << ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT)
733
734/* ----------------------------------------------------- */
735
736#define ddrcReg_PHY_BYTE_LANE_READ_CLEAR_STATUS (1 << 0)
737
738/* ----------------------------------------------------- */
739
740#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_ENABLE (1u << 31)
741#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_RXENB_DISABLE (1 << 19)
742#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_IDDQ_DISABLE (1 << 18)
743#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_REB_DISABLE (1 << 17)
744#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_OEB_DISABLE (1 << 16)
745#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_RXENB_DISABLE (1 << 15)
746#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_IDDQ_DISABLE (1 << 14)
747#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_REB_DISABLE (1 << 13)
748#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_OEB_DISABLE (1 << 12)
749#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_RXENB_DISABLE (1 << 11)
750#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_IDDQ_DISABLE (1 << 10)
751#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_REB_DISABLE (1 << 9)
752#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_OEB_DISABLE (1 << 8)
753#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_RXENB_DISABLE (1 << 7)
754#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_IDDQ_DISABLE (1 << 6)
755#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_REB_DISABLE (1 << 5)
756#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_OEB_DISABLE (1 << 4)
757#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_RXENB_DISABLE (1 << 3)
758#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_IDDQ_DISABLE (1 << 2)
759#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_REB_DISABLE (1 << 1)
760#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_OEB_DISABLE (1 << 0)
761
762/* ----------------------------------------------------- */
763
764#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B_DDR_READ_ENB (1 << 5)
765#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B (1 << 4)
766#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SEL_SSTL18 (1 << 3)
767#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELTXDRV_CI (1 << 2)
768#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELRXDRV (1 << 1)
769#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SLEW (1 << 0)
770
771/* ----------------------------------------------------- */
772
773#define ddrcReg_PHY_BYTE_LANE_PAD_CLK_CTL_DISABLE (1 << 0)
774
775/* ----------------------------------------------------- */
776
777#define ddrcReg_PHY_BYTE_LANE_WRITE_CTL_PREAMBLE_DDR3 (1 << 0)
778
779/* ----------------------------------------------------- */
780
781#define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_HALF (1 << 1)
782#define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_OFF (1 << 0)
783
784/*********************************************************************/
785/* ARM PL341 DDRC to Broadcom DDR23 PHY glue register definitions */
786/*********************************************************************/
787
788 typedef struct {
789 uint32_t cfg;
790 uint32_t actMonCnt;
791 uint32_t ctl;
792 uint32_t lbistCtl;
793 uint32_t lbistSeed;
794 uint32_t lbistStatus;
795 uint32_t tieOff;
796 uint32_t actMonClear;
797 uint32_t status;
798 uint32_t user;
799 } ddrcReg_CTLR_PHY_GLUE_REG_t;
800
801#define ddrcReg_CTLR_PHY_GLUE_OFFSET 0x0700
802#define ddrcReg_CTLR_PHY_GLUE_REGP ((volatile ddrcReg_CTLR_PHY_GLUE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_PHY_GLUE_OFFSET))
803
804/* ----------------------------------------------------- */
805
806/* DDR2 / AXI block phase alignment interrupt control */
807#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT 18
808#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_MASK (0x3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
809#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_OFF (0 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
810#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_TIGHT (1 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
811#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_MEDIUM (2 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
812#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_LOOSE (3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
813
814#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT 17
815#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
816#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_DIFFERENTIAL (0 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
817#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_CMOS (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
818
819#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT 16
820#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
821#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_DEEP (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
822#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
823#define ddrcReg_CTLR_PHY_GLUE_CFG_HW_FIXED_ALIGNMENT_DISABLED ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW
824
825#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT 15
826#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
827#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_BP134 (0 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
828#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
829#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301
830
831/* Software control of PHY VDL updates from control register settings. Bit 13 enables the use of Bit 14. */
832/* If software control is not enabled, then updates occur when a refresh command is issued by the hardware */
833/* controller. If 2 chips selects are being used, then software control must be enabled. */
834#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_LOAD (1 << 14)
835#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_ENABLE (1 << 13)
836
837/* Use these to bypass a pipeline stage. By default the ADDR is off but the BYTE LANE in / out are on. */
838#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_ADDR_CTL_IN_BYPASS_PIPELINE_STAGE (1 << 12)
839#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_IN_BYPASS_PIPELINE_STAGE (1 << 11)
840#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_OUT_BYPASS_PIPELINE_STAGE (1 << 10)
841
842/* Chip select count */
843#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT 9
844#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
845#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_1 (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
846#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_2 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
847
848#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT 8
849#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_ASYNC (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT)
850#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SYNC (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT)
851
852#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT 7
853#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_LOW (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT)
854#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_HIGH (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT)
855
856#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT 6
857#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_LOW (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT)
858#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_HIGH (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT)
859
860#define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT 0
861#define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_MASK (0x7 << ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT)
862
863/* ----------------------------------------------------- */
864#define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT 0
865#define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_MASK (0x7f << ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT)
866
867/* ---- Public Function Prototypes --------------------------------------- */
868
869#ifdef __cplusplus
870} /* end extern "C" */
871#endif
872#endif /* DDRC_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
new file mode 100644
index 000000000000..375066ad0186
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
@@ -0,0 +1,145 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dmacHw_priv.h
18*
19* @brief Private Definitions for low level DMA driver
20*
21*/
22/****************************************************************************/
23
24#ifndef _DMACHW_PRIV_H
25#define _DMACHW_PRIV_H
26
27#include <csp/stdint.h>
28
29/* Data type for DMA Link List Item */
30typedef struct {
31 uint32_t sar; /* Source Adress Register.
32 Address must be aligned to CTLx.SRC_TR_WIDTH. */
33 uint32_t dar; /* Destination Address Register.
34 Address must be aligned to CTLx.DST_TR_WIDTH. */
35 uint32_t llpPhy; /* LLP contains the physical address of the next descriptor for block chaining using linked lists.
36 Address MUST be aligned to a 32-bit boundary. */
37 dmacHw_REG64_t ctl; /* Control Register. 64 bits */
38 uint32_t sstat; /* Source Status Register */
39 uint32_t dstat; /* Destination Status Register */
40 uint32_t devCtl; /* Device specific control information */
41 uint32_t llp; /* LLP contains the virtual address of the next descriptor for block chaining using linked lists. */
42} dmacHw_DESC_t;
43
44/*
45 * Descriptor ring pointers
46 */
47typedef struct {
48 int num; /* Number of link items */
49 dmacHw_DESC_t *pHead; /* Head of descriptor ring (for writing) */
50 dmacHw_DESC_t *pTail; /* Tail of descriptor ring (for reading) */
51 dmacHw_DESC_t *pProg; /* Descriptor to program the channel (for programming the channel register) */
52 dmacHw_DESC_t *pEnd; /* End of current descriptor chain */
53 dmacHw_DESC_t *pFree; /* Descriptor to free memory (freeing dynamic memory) */
54 uint32_t virt2PhyOffset; /* Virtual to physical address offset for the descriptor ring */
55} dmacHw_DESC_RING_t;
56
57/*
58 * DMA channel control block
59 */
60typedef struct {
61 uint32_t module; /* DMA controller module (0-1) */
62 uint32_t channel; /* DMA channel (0-7) */
63 volatile uint32_t varDataStarted; /* Flag indicating variable data channel is enabled */
64 volatile uint32_t descUpdated; /* Flag to indicate descriptor update is complete */
65 void *userData; /* Channel specifc user data */
66} dmacHw_CBLK_t;
67
68#define dmacHw_ASSERT(a) if (!(a)) while (1)
69#define dmacHw_MAX_CHANNEL_COUNT 16
70#define dmacHw_FREE_USER_MEMORY 0xFFFFFFFF
71#define dmacHw_DESC_FREE dmacHw_REG_CTL_DONE
72#define dmacHw_DESC_INIT ((dmacHw_DESC_t *) 0xFFFFFFFF)
73#define dmacHw_MAX_BLOCKSIZE 4064
74#define dmacHw_GET_DESC_RING(addr) (dmacHw_DESC_RING_t *)(addr)
75#define dmacHw_ADDRESS_MASK(byte) ((byte) - 1)
76#define dmacHw_NEXT_DESC(rp, dp) ((rp)->dp = (dmacHw_DESC_t *)(rp)->dp->llp)
77#define dmacHw_HANDLE_TO_CBLK(handle) ((dmacHw_CBLK_t *) (handle))
78#define dmacHw_CBLK_TO_HANDLE(cblkp) ((dmacHw_HANDLE_t) (cblkp))
79#define dmacHw_DST_IS_MEMORY(tt) (((tt) == dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) || ((tt) == dmacHw_TRANSFER_TYPE_MEM_TO_MEM)) ? 1 : 0
80
81/****************************************************************************/
82/**
83* @brief Get next available transaction width
84*
85*
86* @return On sucess : Next avail able transaction width
87* On failure : dmacHw_TRANSACTION_WIDTH_8
88*
89* @note
90* None
91*/
92/****************************************************************************/
93static inline dmacHw_TRANSACTION_WIDTH_e dmacHw_GetNextTrWidth(dmacHw_TRANSACTION_WIDTH_e tw /* [ IN ] Current transaction width */
94 ) {
95 if (tw & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) {
96 return ((tw >> dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT) -
97 1) << dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT;
98 } else if (tw & dmacHw_REG_CTL_DST_TR_WIDTH_MASK) {
99 return ((tw >> dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT) -
100 1) << dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT;
101 }
102
103 /* Default return */
104 return dmacHw_SRC_TRANSACTION_WIDTH_8;
105}
106
107/****************************************************************************/
108/**
109* @brief Get number of bytes per transaction
110*
111* @return Number of bytes per transaction
112*
113*
114* @note
115* None
116*/
117/****************************************************************************/
118static inline int dmacHw_GetTrWidthInBytes(dmacHw_TRANSACTION_WIDTH_e tw /* [ IN ] Transaction width */
119 ) {
120 int width = 1;
121 switch (tw) {
122 case dmacHw_SRC_TRANSACTION_WIDTH_8:
123 width = 1;
124 break;
125 case dmacHw_SRC_TRANSACTION_WIDTH_16:
126 case dmacHw_DST_TRANSACTION_WIDTH_16:
127 width = 2;
128 break;
129 case dmacHw_SRC_TRANSACTION_WIDTH_32:
130 case dmacHw_DST_TRANSACTION_WIDTH_32:
131 width = 4;
132 break;
133 case dmacHw_SRC_TRANSACTION_WIDTH_64:
134 case dmacHw_DST_TRANSACTION_WIDTH_64:
135 width = 8;
136 break;
137 default:
138 dmacHw_ASSERT(0);
139 }
140
141 /* Default transaction width */
142 return width;
143}
144
145#endif /* _DMACHW_PRIV_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h
new file mode 100644
index 000000000000..891cea87e333
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h
@@ -0,0 +1,406 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dmacHw_reg.h
18*
19* @brief Definitions for low level DMA registers
20*
21*/
22/****************************************************************************/
23
24#ifndef _DMACHW_REG_H
25#define _DMACHW_REG_H
26
27#include <csp/stdint.h>
28#include <mach/csp/mm_io.h>
29
30/* Data type for 64 bit little endian register */
31typedef struct {
32 volatile uint32_t lo; /* Lower 32 bit in little endian mode */
33 volatile uint32_t hi; /* Upper 32 bit in little endian mode */
34} dmacHw_REG64_t;
35
36/* Data type representing DMA channel registers */
37typedef struct {
38 dmacHw_REG64_t ChannelSar; /* Source Adress Register. 64 bits (upper 32 bits are reserved)
39 Address must be aligned to CTLx.SRC_TR_WIDTH.
40 */
41 dmacHw_REG64_t ChannelDar; /* Destination Address Register.64 bits (upper 32 bits are reserved)
42 Address must be aligned to CTLx.DST_TR_WIDTH.
43 */
44 dmacHw_REG64_t ChannelLlp; /* Link List Pointer.64 bits (upper 32 bits are reserved)
45 LLP contains the pointer to the next LLI for block chaining using linked lists.
46 If LLPis set to 0x0, then transfers using linked lists are not enabled.
47 Address MUST be aligned to a 32-bit boundary.
48 */
49 dmacHw_REG64_t ChannelCtl; /* Control Register. 64 bits */
50 dmacHw_REG64_t ChannelSstat; /* Source Status Register */
51 dmacHw_REG64_t ChannelDstat; /* Destination Status Register */
52 dmacHw_REG64_t ChannelSstatAddr; /* Source Status Address Register */
53 dmacHw_REG64_t ChannelDstatAddr; /* Destination Status Address Register */
54 dmacHw_REG64_t ChannelConfig; /* Channel Configuration Register */
55 dmacHw_REG64_t SrcGather; /* Source gather register */
56 dmacHw_REG64_t DstScatter; /* Destination scatter register */
57} dmacHw_CH_REG_t;
58
59/* Data type for RAW interrupt status registers */
60typedef struct {
61 dmacHw_REG64_t RawTfr; /* Raw Status for IntTfr Interrupt */
62 dmacHw_REG64_t RawBlock; /* Raw Status for IntBlock Interrupt */
63 dmacHw_REG64_t RawSrcTran; /* Raw Status for IntSrcTran Interrupt */
64 dmacHw_REG64_t RawDstTran; /* Raw Status for IntDstTran Interrupt */
65 dmacHw_REG64_t RawErr; /* Raw Status for IntErr Interrupt */
66} dmacHw_INT_RAW_t;
67
68/* Data type for interrupt status registers */
69typedef struct {
70 dmacHw_REG64_t StatusTfr; /* Status for IntTfr Interrupt */
71 dmacHw_REG64_t StatusBlock; /* Status for IntBlock Interrupt */
72 dmacHw_REG64_t StatusSrcTran; /* Status for IntSrcTran Interrupt */
73 dmacHw_REG64_t StatusDstTran; /* Status for IntDstTran Interrupt */
74 dmacHw_REG64_t StatusErr; /* Status for IntErr Interrupt */
75} dmacHw_INT_STATUS_t;
76
77/* Data type for interrupt mask registers*/
78typedef struct {
79 dmacHw_REG64_t MaskTfr; /* Mask for IntTfr Interrupt */
80 dmacHw_REG64_t MaskBlock; /* Mask for IntBlock Interrupt */
81 dmacHw_REG64_t MaskSrcTran; /* Mask for IntSrcTran Interrupt */
82 dmacHw_REG64_t MaskDstTran; /* Mask for IntDstTran Interrupt */
83 dmacHw_REG64_t MaskErr; /* Mask for IntErr Interrupt */
84} dmacHw_INT_MASK_t;
85
86/* Data type for interrupt clear registers */
87typedef struct {
88 dmacHw_REG64_t ClearTfr; /* Clear for IntTfr Interrupt */
89 dmacHw_REG64_t ClearBlock; /* Clear for IntBlock Interrupt */
90 dmacHw_REG64_t ClearSrcTran; /* Clear for IntSrcTran Interrupt */
91 dmacHw_REG64_t ClearDstTran; /* Clear for IntDstTran Interrupt */
92 dmacHw_REG64_t ClearErr; /* Clear for IntErr Interrupt */
93 dmacHw_REG64_t StatusInt; /* Status for each interrupt type */
94} dmacHw_INT_CLEAR_t;
95
96/* Data type for software handshaking registers */
97typedef struct {
98 dmacHw_REG64_t ReqSrcReg; /* Source Software Transaction Request Register */
99 dmacHw_REG64_t ReqDstReg; /* Destination Software Transaction Request Register */
100 dmacHw_REG64_t SglReqSrcReg; /* Single Source Transaction Request Register */
101 dmacHw_REG64_t SglReqDstReg; /* Single Destination Transaction Request Register */
102 dmacHw_REG64_t LstSrcReg; /* Last Source Transaction Request Register */
103 dmacHw_REG64_t LstDstReg; /* Last Destination Transaction Request Register */
104} dmacHw_SW_HANDSHAKE_t;
105
106/* Data type for misc. registers */
107typedef struct {
108 dmacHw_REG64_t DmaCfgReg; /* DMA Configuration Register */
109 dmacHw_REG64_t ChEnReg; /* DMA Channel Enable Register */
110 dmacHw_REG64_t DmaIdReg; /* DMA ID Register */
111 dmacHw_REG64_t DmaTestReg; /* DMA Test Register */
112 dmacHw_REG64_t Reserved0; /* Reserved */
113 dmacHw_REG64_t Reserved1; /* Reserved */
114 dmacHw_REG64_t CompParm6; /* Component Parameter 6 */
115 dmacHw_REG64_t CompParm5; /* Component Parameter 5 */
116 dmacHw_REG64_t CompParm4; /* Component Parameter 4 */
117 dmacHw_REG64_t CompParm3; /* Component Parameter 3 */
118 dmacHw_REG64_t CompParm2; /* Component Parameter 2 */
119 dmacHw_REG64_t CompParm1; /* Component Parameter 1 */
120 dmacHw_REG64_t CompId; /* Compoent ID */
121} dmacHw_MISC_t;
122
123/* Base registers */
124#define dmacHw_0_MODULE_BASE_ADDR (char *) MM_IO_BASE_DMA0 /* DMAC 0 module's base address */
125#define dmacHw_1_MODULE_BASE_ADDR (char *) MM_IO_BASE_DMA1 /* DMAC 1 module's base address */
126
127extern uint32_t dmaChannelCount_0;
128extern uint32_t dmaChannelCount_1;
129
130/* Define channel specific registers */
131#define dmacHw_CHAN_BASE(module, chan) ((dmacHw_CH_REG_t *) ((char *)((module) ? dmacHw_1_MODULE_BASE_ADDR : dmacHw_0_MODULE_BASE_ADDR) + ((chan) * sizeof(dmacHw_CH_REG_t))))
132
133/* Raw interrupt status registers */
134#define dmacHw_REG_INT_RAW_BASE(module) ((char *)dmacHw_CHAN_BASE((module), ((module) ? dmaChannelCount_1 : dmaChannelCount_0)))
135#define dmacHw_REG_INT_RAW_TRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawTfr.lo)
136#define dmacHw_REG_INT_RAW_BLOCK(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawBlock.lo)
137#define dmacHw_REG_INT_RAW_STRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawSrcTran.lo)
138#define dmacHw_REG_INT_RAW_DTRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawDstTran.lo)
139#define dmacHw_REG_INT_RAW_ERROR(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawErr.lo)
140
141/* Interrupt status registers */
142#define dmacHw_REG_INT_STAT_BASE(module) ((char *)(dmacHw_REG_INT_RAW_BASE((module)) + sizeof(dmacHw_INT_RAW_t)))
143#define dmacHw_REG_INT_STAT_TRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusTfr.lo)
144#define dmacHw_REG_INT_STAT_BLOCK(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusBlock.lo)
145#define dmacHw_REG_INT_STAT_STRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusSrcTran.lo)
146#define dmacHw_REG_INT_STAT_DTRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusDstTran.lo)
147#define dmacHw_REG_INT_STAT_ERROR(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusErr.lo)
148
149/* Interrupt status registers */
150#define dmacHw_REG_INT_MASK_BASE(module) ((char *)(dmacHw_REG_INT_STAT_BASE((module)) + sizeof(dmacHw_INT_STATUS_t)))
151#define dmacHw_REG_INT_MASK_TRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskTfr.lo)
152#define dmacHw_REG_INT_MASK_BLOCK(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskBlock.lo)
153#define dmacHw_REG_INT_MASK_STRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskSrcTran.lo)
154#define dmacHw_REG_INT_MASK_DTRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskDstTran.lo)
155#define dmacHw_REG_INT_MASK_ERROR(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskErr.lo)
156
157/* Interrupt clear registers */
158#define dmacHw_REG_INT_CLEAR_BASE(module) ((char *)(dmacHw_REG_INT_MASK_BASE((module)) + sizeof(dmacHw_INT_MASK_t)))
159#define dmacHw_REG_INT_CLEAR_TRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearTfr.lo)
160#define dmacHw_REG_INT_CLEAR_BLOCK(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearBlock.lo)
161#define dmacHw_REG_INT_CLEAR_STRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearSrcTran.lo)
162#define dmacHw_REG_INT_CLEAR_DTRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearDstTran.lo)
163#define dmacHw_REG_INT_CLEAR_ERROR(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearErr.lo)
164#define dmacHw_REG_INT_STATUS(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->StatusInt.lo)
165
166/* Software handshaking registers */
167#define dmacHw_REG_SW_HS_BASE(module) ((char *)(dmacHw_REG_INT_CLEAR_BASE((module)) + sizeof(dmacHw_INT_CLEAR_t)))
168#define dmacHw_REG_SW_HS_SRC_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqSrcReg.lo)
169#define dmacHw_REG_SW_HS_DST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqDstReg.lo)
170#define dmacHw_REG_SW_HS_SRC_SGL_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqSrcReg.lo)
171#define dmacHw_REG_SW_HS_DST_SGL_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqDstReg.lo)
172#define dmacHw_REG_SW_HS_SRC_LST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstSrcReg.lo)
173#define dmacHw_REG_SW_HS_DST_LST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstDstReg.lo)
174
175/* Miscellaneous registers */
176#define dmacHw_REG_MISC_BASE(module) ((char *)(dmacHw_REG_SW_HS_BASE((module)) + sizeof(dmacHw_SW_HANDSHAKE_t)))
177#define dmacHw_REG_MISC_CFG(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaCfgReg.lo)
178#define dmacHw_REG_MISC_CH_ENABLE(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->ChEnReg.lo)
179#define dmacHw_REG_MISC_ID(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaIdReg.lo)
180#define dmacHw_REG_MISC_TEST(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaTestReg.lo)
181#define dmacHw_REG_MISC_COMP_PARAM1_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.lo)
182#define dmacHw_REG_MISC_COMP_PARAM1_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.hi)
183#define dmacHw_REG_MISC_COMP_PARAM2_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.lo)
184#define dmacHw_REG_MISC_COMP_PARAM2_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.hi)
185#define dmacHw_REG_MISC_COMP_PARAM3_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.lo)
186#define dmacHw_REG_MISC_COMP_PARAM3_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.hi)
187#define dmacHw_REG_MISC_COMP_PARAM4_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.lo)
188#define dmacHw_REG_MISC_COMP_PARAM4_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.hi)
189#define dmacHw_REG_MISC_COMP_PARAM5_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.lo)
190#define dmacHw_REG_MISC_COMP_PARAM5_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.hi)
191#define dmacHw_REG_MISC_COMP_PARAM6_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.lo)
192#define dmacHw_REG_MISC_COMP_PARAM6_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.hi)
193
194/* Channel control registers */
195#define dmacHw_REG_SAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSar.lo)
196#define dmacHw_REG_DAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDar.lo)
197#define dmacHw_REG_LLP(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelLlp.lo)
198
199#define dmacHw_REG_CTL_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.lo)
200#define dmacHw_REG_CTL_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.hi)
201
202#define dmacHw_REG_SSTAT(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSstat.lo)
203#define dmacHw_REG_DSTAT(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDstat.lo)
204#define dmacHw_REG_SSTATAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSstatAddr.lo)
205#define dmacHw_REG_DSTATAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDstatAddr.lo)
206
207#define dmacHw_REG_CFG_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.lo)
208#define dmacHw_REG_CFG_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.hi)
209
210#define dmacHw_REG_SGR_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->SrcGather.lo)
211#define dmacHw_REG_SGR_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->SrcGather.hi)
212
213#define dmacHw_REG_DSR_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->DstScatter.lo)
214#define dmacHw_REG_DSR_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->DstScatter.hi)
215
216#define INT_STATUS_MASK(channel) (0x00000001 << (channel))
217#define CHANNEL_BUSY(mod, channel) (dmacHw_REG_MISC_CH_ENABLE((mod)) & (0x00000001 << (channel)))
218
219/* Bit mask for REG_DMACx_CTL_LO */
220
221#define dmacHw_REG_CTL_INT_EN 0x00000001 /* Channel interrupt enable */
222
223#define dmacHw_REG_CTL_DST_TR_WIDTH_MASK 0x0000000E /* Destination transaction width mask */
224#define dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT 1
225#define dmacHw_REG_CTL_DST_TR_WIDTH_8 0x00000000 /* Destination transaction width 8 bit */
226#define dmacHw_REG_CTL_DST_TR_WIDTH_16 0x00000002 /* Destination transaction width 16 bit */
227#define dmacHw_REG_CTL_DST_TR_WIDTH_32 0x00000004 /* Destination transaction width 32 bit */
228#define dmacHw_REG_CTL_DST_TR_WIDTH_64 0x00000006 /* Destination transaction width 64 bit */
229
230#define dmacHw_REG_CTL_SRC_TR_WIDTH_MASK 0x00000070 /* Source transaction width mask */
231#define dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT 4
232#define dmacHw_REG_CTL_SRC_TR_WIDTH_8 0x00000000 /* Source transaction width 8 bit */
233#define dmacHw_REG_CTL_SRC_TR_WIDTH_16 0x00000010 /* Source transaction width 16 bit */
234#define dmacHw_REG_CTL_SRC_TR_WIDTH_32 0x00000020 /* Source transaction width 32 bit */
235#define dmacHw_REG_CTL_SRC_TR_WIDTH_64 0x00000030 /* Source transaction width 64 bit */
236
237#define dmacHw_REG_CTL_DS_ENABLE 0x00040000 /* Destination scatter enable */
238#define dmacHw_REG_CTL_SG_ENABLE 0x00020000 /* Source gather enable */
239
240#define dmacHw_REG_CTL_DINC_MASK 0x00000180 /* Destination address inc/dec mask */
241#define dmacHw_REG_CTL_DINC_INC 0x00000000 /* Destination address increment */
242#define dmacHw_REG_CTL_DINC_DEC 0x00000080 /* Destination address decrement */
243#define dmacHw_REG_CTL_DINC_NC 0x00000100 /* Destination address no change */
244
245#define dmacHw_REG_CTL_SINC_MASK 0x00000600 /* Source address inc/dec mask */
246#define dmacHw_REG_CTL_SINC_INC 0x00000000 /* Source address increment */
247#define dmacHw_REG_CTL_SINC_DEC 0x00000200 /* Source address decrement */
248#define dmacHw_REG_CTL_SINC_NC 0x00000400 /* Source address no change */
249
250#define dmacHw_REG_CTL_DST_MSIZE_MASK 0x00003800 /* Destination burst transaction length */
251#define dmacHw_REG_CTL_DST_MSIZE_0 0x00000000 /* No Destination burst */
252#define dmacHw_REG_CTL_DST_MSIZE_4 0x00000800 /* Destination burst transaction length 4 */
253#define dmacHw_REG_CTL_DST_MSIZE_8 0x00001000 /* Destination burst transaction length 8 */
254#define dmacHw_REG_CTL_DST_MSIZE_16 0x00001800 /* Destination burst transaction length 16 */
255
256#define dmacHw_REG_CTL_SRC_MSIZE_MASK 0x0001C000 /* Source burst transaction length */
257#define dmacHw_REG_CTL_SRC_MSIZE_0 0x00000000 /* No Source burst */
258#define dmacHw_REG_CTL_SRC_MSIZE_4 0x00004000 /* Source burst transaction length 4 */
259#define dmacHw_REG_CTL_SRC_MSIZE_8 0x00008000 /* Source burst transaction length 8 */
260#define dmacHw_REG_CTL_SRC_MSIZE_16 0x0000C000 /* Source burst transaction length 16 */
261
262#define dmacHw_REG_CTL_TTFC_MASK 0x00700000 /* Transfer type and flow controller */
263#define dmacHw_REG_CTL_TTFC_MM_DMAC 0x00000000 /* Memory to Memory with DMAC as flow controller */
264#define dmacHw_REG_CTL_TTFC_MP_DMAC 0x00100000 /* Memory to Peripheral with DMAC as flow controller */
265#define dmacHw_REG_CTL_TTFC_PM_DMAC 0x00200000 /* Peripheral to Memory with DMAC as flow controller */
266#define dmacHw_REG_CTL_TTFC_PP_DMAC 0x00300000 /* Peripheral to Peripheral with DMAC as flow controller */
267#define dmacHw_REG_CTL_TTFC_PM_PERI 0x00400000 /* Peripheral to Memory with Peripheral as flow controller */
268#define dmacHw_REG_CTL_TTFC_PP_SPERI 0x00500000 /* Peripheral to Peripheral with Source Peripheral as flow controller */
269#define dmacHw_REG_CTL_TTFC_MP_PERI 0x00600000 /* Memory to Peripheral with Peripheral as flow controller */
270#define dmacHw_REG_CTL_TTFC_PP_DPERI 0x00700000 /* Peripheral to Peripheral with Destination Peripheral as flow controller */
271
272#define dmacHw_REG_CTL_DMS_MASK 0x01800000 /* Destination AHB master interface */
273#define dmacHw_REG_CTL_DMS_1 0x00000000 /* Destination AHB master interface 1 */
274#define dmacHw_REG_CTL_DMS_2 0x00800000 /* Destination AHB master interface 2 */
275
276#define dmacHw_REG_CTL_SMS_MASK 0x06000000 /* Source AHB master interface */
277#define dmacHw_REG_CTL_SMS_1 0x00000000 /* Source AHB master interface 1 */
278#define dmacHw_REG_CTL_SMS_2 0x02000000 /* Source AHB master interface 2 */
279
280#define dmacHw_REG_CTL_LLP_DST_EN 0x08000000 /* Block chaining enable for destination side */
281#define dmacHw_REG_CTL_LLP_SRC_EN 0x10000000 /* Block chaining enable for source side */
282
283/* Bit mask for REG_DMACx_CTL_HI */
284#define dmacHw_REG_CTL_BLOCK_TS_MASK 0x00000FFF /* Block transfer size */
285#define dmacHw_REG_CTL_DONE 0x00001000 /* Block trasnfer done */
286
287/* Bit mask for REG_DMACx_CFG_LO */
288#define dmacHw_REG_CFG_LO_CH_PRIORITY_SHIFT 5 /* Channel priority shift */
289#define dmacHw_REG_CFG_LO_CH_PRIORITY_MASK 0x000000E0 /* Channel priority mask */
290#define dmacHw_REG_CFG_LO_CH_PRIORITY_0 0x00000000 /* Channel priority 0 */
291#define dmacHw_REG_CFG_LO_CH_PRIORITY_1 0x00000020 /* Channel priority 1 */
292#define dmacHw_REG_CFG_LO_CH_PRIORITY_2 0x00000040 /* Channel priority 2 */
293#define dmacHw_REG_CFG_LO_CH_PRIORITY_3 0x00000060 /* Channel priority 3 */
294#define dmacHw_REG_CFG_LO_CH_PRIORITY_4 0x00000080 /* Channel priority 4 */
295#define dmacHw_REG_CFG_LO_CH_PRIORITY_5 0x000000A0 /* Channel priority 5 */
296#define dmacHw_REG_CFG_LO_CH_PRIORITY_6 0x000000C0 /* Channel priority 6 */
297#define dmacHw_REG_CFG_LO_CH_PRIORITY_7 0x000000E0 /* Channel priority 7 */
298
299#define dmacHw_REG_CFG_LO_CH_SUSPEND 0x00000100 /* Channel suspend */
300#define dmacHw_REG_CFG_LO_CH_FIFO_EMPTY 0x00000200 /* Channel FIFO empty */
301#define dmacHw_REG_CFG_LO_DST_CH_SW_HS 0x00000400 /* Destination channel SW handshaking */
302#define dmacHw_REG_CFG_LO_SRC_CH_SW_HS 0x00000800 /* Source channel SW handshaking */
303
304#define dmacHw_REG_CFG_LO_CH_LOCK_MASK 0x00003000 /* Channel locking mask */
305#define dmacHw_REG_CFG_LO_CH_LOCK_DMA 0x00000000 /* Channel lock over the entire DMA transfer operation */
306#define dmacHw_REG_CFG_LO_CH_LOCK_BLOCK 0x00001000 /* Channel lock over the block transfer operation */
307#define dmacHw_REG_CFG_LO_CH_LOCK_TRANS 0x00002000 /* Channel lock over the transaction */
308#define dmacHw_REG_CFG_LO_CH_LOCK_ENABLE 0x00010000 /* Channel lock enable */
309
310#define dmacHw_REG_CFG_LO_BUS_LOCK_MASK 0x0000C000 /* Bus locking mask */
311#define dmacHw_REG_CFG_LO_BUS_LOCK_DMA 0x00000000 /* Bus lock over the entire DMA transfer operation */
312#define dmacHw_REG_CFG_LO_BUS_LOCK_BLOCK 0x00004000 /* Bus lock over the block transfer operation */
313#define dmacHw_REG_CFG_LO_BUS_LOCK_TRANS 0x00008000 /* Bus lock over the transaction */
314#define dmacHw_REG_CFG_LO_BUS_LOCK_ENABLE 0x00020000 /* Bus lock enable */
315
316#define dmacHw_REG_CFG_LO_DST_HS_POLARITY_LOW 0x00040000 /* Destination channel handshaking signal polarity low */
317#define dmacHw_REG_CFG_LO_SRC_HS_POLARITY_LOW 0x00080000 /* Source channel handshaking signal polarity low */
318
319#define dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK 0x3FF00000 /* Maximum AMBA burst length */
320
321#define dmacHw_REG_CFG_LO_AUTO_RELOAD_SRC 0x40000000 /* Source address auto reload */
322#define dmacHw_REG_CFG_LO_AUTO_RELOAD_DST 0x80000000 /* Destination address auto reload */
323
324/* Bit mask for REG_DMACx_CFG_HI */
325#define dmacHw_REG_CFG_HI_FC_DST_READY 0x00000001 /* Source transaction request is serviced when destination is ready */
326#define dmacHw_REG_CFG_HI_FIFO_ENOUGH 0x00000002 /* Initiate burst transaction when enough data in available in FIFO */
327
328#define dmacHw_REG_CFG_HI_AHB_HPROT_MASK 0x0000001C /* AHB protection mask */
329#define dmacHw_REG_CFG_HI_AHB_HPROT_1 0x00000004 /* AHB protection 1 */
330#define dmacHw_REG_CFG_HI_AHB_HPROT_2 0x00000008 /* AHB protection 2 */
331#define dmacHw_REG_CFG_HI_AHB_HPROT_3 0x00000010 /* AHB protection 3 */
332
333#define dmacHw_REG_CFG_HI_UPDATE_DST_STAT 0x00000020 /* Destination status update enable */
334#define dmacHw_REG_CFG_HI_UPDATE_SRC_STAT 0x00000040 /* Source status update enable */
335
336#define dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK 0x00000780 /* Source peripheral hardware interface mask */
337#define dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK 0x00007800 /* Destination peripheral hardware interface mask */
338
339/* DMA Configuration Parameters */
340#define dmacHw_REG_COMP_PARAM_NUM_CHANNELS 0x00000700 /* Number of channels */
341#define dmacHw_REG_COMP_PARAM_NUM_INTERFACE 0x00001800 /* Number of master interface */
342#define dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE 0x0000000f /* Maximum brust size */
343#define dmacHw_REG_COMP_PARAM_DATA_WIDTH 0x00006000 /* Data transfer width */
344
345/* Define GET/SET macros to program the registers */
346#define dmacHw_SET_SAR(module, channel, addr) (dmacHw_REG_SAR((module), (channel)) = (uint32_t) (addr))
347#define dmacHw_SET_DAR(module, channel, addr) (dmacHw_REG_DAR((module), (channel)) = (uint32_t) (addr))
348#define dmacHw_SET_LLP(module, channel, ptr) (dmacHw_REG_LLP((module), (channel)) = (uint32_t) (ptr))
349
350#define dmacHw_GET_SSTAT(module, channel) (dmacHw_REG_SSTAT((module), (channel)))
351#define dmacHw_GET_DSTAT(module, channel) (dmacHw_REG_DSTAT((module), (channel)))
352
353#define dmacHw_SET_SSTATAR(module, channel, addr) (dmacHw_REG_SSTATAR((module), (channel)) = (uint32_t) (addr))
354#define dmacHw_SET_DSTATAR(module, channel, addr) (dmacHw_REG_DSTATAR((module), (channel)) = (uint32_t) (addr))
355
356#define dmacHw_SET_CONTROL_LO(module, channel, ctl) (dmacHw_REG_CTL_LO((module), (channel)) |= (ctl))
357#define dmacHw_RESET_CONTROL_LO(module, channel) (dmacHw_REG_CTL_LO((module), (channel)) = 0)
358#define dmacHw_GET_CONTROL_LO(module, channel) (dmacHw_REG_CTL_LO((module), (channel)))
359
360#define dmacHw_SET_CONTROL_HI(module, channel, ctl) (dmacHw_REG_CTL_HI((module), (channel)) |= (ctl))
361#define dmacHw_RESET_CONTROL_HI(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) = 0)
362#define dmacHw_GET_CONTROL_HI(module, channel) (dmacHw_REG_CTL_HI((module), (channel)))
363
364#define dmacHw_GET_BLOCK_SIZE(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_BLOCK_TS_MASK)
365#define dmacHw_DMA_COMPLETE(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_DONE)
366
367#define dmacHw_SET_CONFIG_LO(module, channel, cfg) (dmacHw_REG_CFG_LO((module), (channel)) |= (cfg))
368#define dmacHw_RESET_CONFIG_LO(module, channel) (dmacHw_REG_CFG_LO((module), (channel)) = 0)
369#define dmacHw_GET_CONFIG_LO(module, channel) (dmacHw_REG_CFG_LO((module), (channel)))
370#define dmacHw_SET_AMBA_BUSRT_LEN(module, channel, len) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK)) | (((len) << 20) & dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK))
371#define dmacHw_SET_CHANNEL_PRIORITY(module, channel, prio) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_CH_PRIORITY_MASK)) | (prio))
372#define dmacHw_SET_AHB_HPROT(module, channel, protect) (dmacHw_REG_CFG_HI(module, channel) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_AHB_HPROT_MASK)) | (protect))
373
374#define dmacHw_SET_CONFIG_HI(module, channel, cfg) (dmacHw_REG_CFG_HI((module), (channel)) |= (cfg))
375#define dmacHw_RESET_CONFIG_HI(module, channel) (dmacHw_REG_CFG_HI((module), (channel)) = 0)
376#define dmacHw_GET_CONFIG_HI(module, channel) (dmacHw_REG_CFG_HI((module), (channel)))
377#define dmacHw_SET_SRC_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)) | (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK))
378#define dmacHw_SRC_PERI_INTF(intf) (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)
379#define dmacHw_SET_DST_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)) | (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK))
380#define dmacHw_DST_PERI_INTF(intf) (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)
381
382#define dmacHw_DMA_START(module, channel) (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
383#define dmacHw_DMA_STOP(module, channel) (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)))
384#define dmacHw_DMA_ENABLE(module) (dmacHw_REG_MISC_CFG((module)) = 1)
385#define dmacHw_DMA_DISABLE(module) (dmacHw_REG_MISC_CFG((module)) = 0)
386
387#define dmacHw_TRAN_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
388#define dmacHw_BLOCK_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
389#define dmacHw_ERROR_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
390
391#define dmacHw_TRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)))
392#define dmacHw_BLOCK_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)))
393#define dmacHw_ERROR_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)))
394#define dmacHw_STRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_STRAN((module)) = (0x00000001 << ((channel) + 8)))
395#define dmacHw_DTRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_DTRAN((module)) = (0x00000001 << ((channel) + 8)))
396
397#define dmacHw_TRAN_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_TRAN((module)) = (0x00000001 << (channel)))
398#define dmacHw_BLOCK_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_BLOCK((module)) = (0x00000001 << (channel)))
399#define dmacHw_ERROR_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_ERROR((module)) = (0x00000001 << (channel)))
400
401#define dmacHw_GET_NUM_CHANNEL(module) (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_CHANNELS) >> 8) + 1)
402#define dmacHw_GET_NUM_INTERFACE(module) (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_INTERFACE) >> 11) + 1)
403#define dmacHw_GET_MAX_BLOCK_SIZE(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_LO((module)) >> (4 * (channel))) & dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE)
404#define dmacHw_GET_CHANNEL_DATA_WIDTH(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_DATA_WIDTH) >> 13)
405
406#endif /* _DMACHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h
new file mode 100644
index 000000000000..cfa91bed9d34
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h
@@ -0,0 +1,73 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15
16#ifndef CSP_HW_CFG_H
17#define CSP_HW_CFG_H
18
19/* ---- Include Files ---------------------------------------------------- */
20
21#include <cfg_global.h>
22#include <mach/csp/cap_inline.h>
23
24#if defined(__KERNEL__)
25#include <mach/memory_settings.h>
26#else
27#include <hw_cfg.h>
28#endif
29
30/* Some items that can be defined externally, but will be set to default values */
31/* if they are not defined. */
32/* HW_CFG_PLL_SPREAD_SPECTRUM_DISABLE Default undefined and SS is enabled. */
33/* HW_CFG_SDRAM_CAS_LATENCY 5 Default 5, Values [3..6] */
34/* HW_CFG_SDRAM_CHIP_SELECT_CNT 1 Default 1, Vaules [1..2] */
35/* HW_CFG_SDRAM_SPEED_GRADE 667 Default 667, Values [400,533,667,800] */
36/* HW_CFG_SDRAM_WIDTH_BITS 16 Default 16, Vaules [8,16] */
37/* HW_CFG_SDRAM_ADDR_BRC Default undefined and Row-Bank-Col (RBC) addressing used. Define to use Bank-Row-Col (BRC). */
38/* HW_CFG_SDRAM_CLK_ASYNC Default undefined and DDR clock is synchronous with AXI BUS clock. Define for ASYNC mode. */
39
40#if defined(CFG_GLOBAL_CHIP)
41 #if (CFG_GLOBAL_CHIP == FPGA11107)
42 #define HW_CFG_BUS_CLK_HZ 5000000
43 #define HW_CFG_DDR_CTLR_CLK_HZ 10000000
44 #define HW_CFG_DDR_PHY_OMIT
45 #define HW_CFG_UART_CLK_HZ 7500000
46 #else
47 #define HW_CFG_PLL_VCO_HZ 2000000000
48 #define HW_CFG_PLL2_VCO_HZ 1800000000
49 #define HW_CFG_ARM_CLK_HZ CAP_HW_CFG_ARM_CLK_HZ
50 #define HW_CFG_BUS_CLK_HZ 166666666
51 #define HW_CFG_DDR_CTLR_CLK_HZ 333333333
52 #define HW_CFG_DDR_PHY_CLK_HZ (2 * HW_CFG_DDR_CTLR_CLK_HZ)
53 #define HW_CFG_UART_CLK_HZ 142857142
54 #define HW_CFG_VPM_CLK_HZ CAP_HW_CFG_VPM_CLK_HZ
55 #endif
56#else
57 #define HW_CFG_PLL_VCO_HZ 1800000000
58 #define HW_CFG_PLL2_VCO_HZ 1800000000
59 #define HW_CFG_ARM_CLK_HZ 450000000
60 #define HW_CFG_BUS_CLK_HZ 150000000
61 #define HW_CFG_DDR_CTLR_CLK_HZ 300000000
62 #define HW_CFG_DDR_PHY_CLK_HZ (2 * HW_CFG_DDR_CTLR_CLK_HZ)
63 #define HW_CFG_UART_CLK_HZ 150000000
64 #define HW_CFG_VPM_CLK_HZ 300000000
65#endif
66
67/* ---- Public Constants and Types --------------------------------------- */
68/* ---- Public Variable Externs ------------------------------------------ */
69/* ---- Public Function Prototypes --------------------------------------- */
70
71
72#endif /* CSP_HW_CFG_H */
73
diff --git a/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h
new file mode 100644
index 000000000000..e01fc4607c91
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h
@@ -0,0 +1,246 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file intcHw_reg.h
18*
19* @brief platform specific interrupt controller bit assignments
20*
21* @note
22* None
23*/
24/****************************************************************************/
25
26#ifndef _INTCHW_REG_H
27#define _INTCHW_REG_H
28
29/* ---- Include Files ---------------------------------------------------- */
30#include <csp/stdint.h>
31#include <csp/reg.h>
32#include <mach/csp/mm_io.h>
33
34/* ---- Public Constants and Types --------------------------------------- */
35
36#define INTCHW_NUM_IRQ_PER_INTC 32 /* Maximum number of interrupt controllers */
37#define INTCHW_NUM_INTC 3
38
39/* Defines for interrupt controllers. This simplifies and cleans up the function calls. */
40#define INTCHW_INTC0 ((void *)MM_IO_BASE_INTC0)
41#define INTCHW_INTC1 ((void *)MM_IO_BASE_INTC1)
42#define INTCHW_SINTC ((void *)MM_IO_BASE_SINTC)
43
44/* INTC0 - interrupt controller 0 */
45#define INTCHW_INTC0_PIF_BITNUM 31 /* Peripheral interface interrupt */
46#define INTCHW_INTC0_CLCD_BITNUM 30 /* LCD Controller interrupt */
47#define INTCHW_INTC0_GE_BITNUM 29 /* Graphic engine interrupt */
48#define INTCHW_INTC0_APM_BITNUM 28 /* Audio process module interrupt */
49#define INTCHW_INTC0_ESW_BITNUM 27 /* Ethernet switch interrupt */
50#define INTCHW_INTC0_SPIH_BITNUM 26 /* SPI host interrupt */
51#define INTCHW_INTC0_TIMER3_BITNUM 25 /* Timer3 interrupt */
52#define INTCHW_INTC0_TIMER2_BITNUM 24 /* Timer2 interrupt */
53#define INTCHW_INTC0_TIMER1_BITNUM 23 /* Timer1 interrupt */
54#define INTCHW_INTC0_TIMER0_BITNUM 22 /* Timer0 interrupt */
55#define INTCHW_INTC0_SDIOH1_BITNUM 21 /* SDIO1 host interrupt */
56#define INTCHW_INTC0_SDIOH0_BITNUM 20 /* SDIO0 host interrupt */
57#define INTCHW_INTC0_USBD_BITNUM 19 /* USB device interrupt */
58#define INTCHW_INTC0_USBH1_BITNUM 18 /* USB1 host interrupt */
59#define INTCHW_INTC0_USBHD2_BITNUM 17 /* USB host2/device2 interrupt */
60#define INTCHW_INTC0_VPM_BITNUM 16 /* Voice process module interrupt */
61#define INTCHW_INTC0_DMA1C7_BITNUM 15 /* DMA1 channel 7 interrupt */
62#define INTCHW_INTC0_DMA1C6_BITNUM 14 /* DMA1 channel 6 interrupt */
63#define INTCHW_INTC0_DMA1C5_BITNUM 13 /* DMA1 channel 5 interrupt */
64#define INTCHW_INTC0_DMA1C4_BITNUM 12 /* DMA1 channel 4 interrupt */
65#define INTCHW_INTC0_DMA1C3_BITNUM 11 /* DMA1 channel 3 interrupt */
66#define INTCHW_INTC0_DMA1C2_BITNUM 10 /* DMA1 channel 2 interrupt */
67#define INTCHW_INTC0_DMA1C1_BITNUM 9 /* DMA1 channel 1 interrupt */
68#define INTCHW_INTC0_DMA1C0_BITNUM 8 /* DMA1 channel 0 interrupt */
69#define INTCHW_INTC0_DMA0C7_BITNUM 7 /* DMA0 channel 7 interrupt */
70#define INTCHW_INTC0_DMA0C6_BITNUM 6 /* DMA0 channel 6 interrupt */
71#define INTCHW_INTC0_DMA0C5_BITNUM 5 /* DMA0 channel 5 interrupt */
72#define INTCHW_INTC0_DMA0C4_BITNUM 4 /* DMA0 channel 4 interrupt */
73#define INTCHW_INTC0_DMA0C3_BITNUM 3 /* DMA0 channel 3 interrupt */
74#define INTCHW_INTC0_DMA0C2_BITNUM 2 /* DMA0 channel 2 interrupt */
75#define INTCHW_INTC0_DMA0C1_BITNUM 1 /* DMA0 channel 1 interrupt */
76#define INTCHW_INTC0_DMA0C0_BITNUM 0 /* DMA0 channel 0 interrupt */
77
78#define INTCHW_INTC0_PIF (1<<INTCHW_INTC0_PIF_BITNUM)
79#define INTCHW_INTC0_CLCD (1<<INTCHW_INTC0_CLCD_BITNUM)
80#define INTCHW_INTC0_GE (1<<INTCHW_INTC0_GE_BITNUM)
81#define INTCHW_INTC0_APM (1<<INTCHW_INTC0_APM_BITNUM)
82#define INTCHW_INTC0_ESW (1<<INTCHW_INTC0_ESW_BITNUM)
83#define INTCHW_INTC0_SPIH (1<<INTCHW_INTC0_SPIH_BITNUM)
84#define INTCHW_INTC0_TIMER3 (1<<INTCHW_INTC0_TIMER3_BITNUM)
85#define INTCHW_INTC0_TIMER2 (1<<INTCHW_INTC0_TIMER2_BITNUM)
86#define INTCHW_INTC0_TIMER1 (1<<INTCHW_INTC0_TIMER1_BITNUM)
87#define INTCHW_INTC0_TIMER0 (1<<INTCHW_INTC0_TIMER0_BITNUM)
88#define INTCHW_INTC0_SDIOH1 (1<<INTCHW_INTC0_SDIOH1_BITNUM)
89#define INTCHW_INTC0_SDIOH0 (1<<INTCHW_INTC0_SDIOH0_BITNUM)
90#define INTCHW_INTC0_USBD (1<<INTCHW_INTC0_USBD_BITNUM)
91#define INTCHW_INTC0_USBH1 (1<<INTCHW_INTC0_USBH1_BITNUM)
92#define INTCHW_INTC0_USBHD2 (1<<INTCHW_INTC0_USBHD2_BITNUM)
93#define INTCHW_INTC0_VPM (1<<INTCHW_INTC0_VPM_BITNUM)
94#define INTCHW_INTC0_DMA1C7 (1<<INTCHW_INTC0_DMA1C7_BITNUM)
95#define INTCHW_INTC0_DMA1C6 (1<<INTCHW_INTC0_DMA1C6_BITNUM)
96#define INTCHW_INTC0_DMA1C5 (1<<INTCHW_INTC0_DMA1C5_BITNUM)
97#define INTCHW_INTC0_DMA1C4 (1<<INTCHW_INTC0_DMA1C4_BITNUM)
98#define INTCHW_INTC0_DMA1C3 (1<<INTCHW_INTC0_DMA1C3_BITNUM)
99#define INTCHW_INTC0_DMA1C2 (1<<INTCHW_INTC0_DMA1C2_BITNUM)
100#define INTCHW_INTC0_DMA1C1 (1<<INTCHW_INTC0_DMA1C1_BITNUM)
101#define INTCHW_INTC0_DMA1C0 (1<<INTCHW_INTC0_DMA1C0_BITNUM)
102#define INTCHW_INTC0_DMA0C7 (1<<INTCHW_INTC0_DMA0C7_BITNUM)
103#define INTCHW_INTC0_DMA0C6 (1<<INTCHW_INTC0_DMA0C6_BITNUM)
104#define INTCHW_INTC0_DMA0C5 (1<<INTCHW_INTC0_DMA0C5_BITNUM)
105#define INTCHW_INTC0_DMA0C4 (1<<INTCHW_INTC0_DMA0C4_BITNUM)
106#define INTCHW_INTC0_DMA0C3 (1<<INTCHW_INTC0_DMA0C3_BITNUM)
107#define INTCHW_INTC0_DMA0C2 (1<<INTCHW_INTC0_DMA0C2_BITNUM)
108#define INTCHW_INTC0_DMA0C1 (1<<INTCHW_INTC0_DMA0C1_BITNUM)
109#define INTCHW_INTC0_DMA0C0 (1<<INTCHW_INTC0_DMA0C0_BITNUM)
110
111/* INTC1 - interrupt controller 1 */
112#define INTCHW_INTC1_DDRVPMP_BITNUM 27 /* DDR and VPM PLL clock phase relationship interupt (Not for A0) */
113#define INTCHW_INTC1_DDRVPMT_BITNUM 26 /* DDR and VPM HW phase align timeout interrupt (Not for A0) */
114#define INTCHW_INTC1_DDRP_BITNUM 26 /* DDR and PLL clock phase relationship interupt (For A0 only)) */
115#define INTCHW_INTC1_RTC2_BITNUM 25 /* Real time clock tamper interrupt */
116#define INTCHW_INTC1_VDEC_BITNUM 24 /* Hantro Video Decoder interrupt */
117/* Bits 13-23 are non-secure versions of the corresponding secure bits in SINTC bits 0-10. */
118#define INTCHW_INTC1_SPUM_BITNUM 23 /* Secure process module interrupt */
119#define INTCHW_INTC1_RTC1_BITNUM 22 /* Real time clock one-shot interrupt */
120#define INTCHW_INTC1_RTC0_BITNUM 21 /* Real time clock periodic interrupt */
121#define INTCHW_INTC1_RNG_BITNUM 20 /* Random number generator interrupt */
122#define INTCHW_INTC1_FMPU_BITNUM 19 /* Flash memory parition unit interrupt */
123#define INTCHW_INTC1_VMPU_BITNUM 18 /* VRAM memory partition interrupt */
124#define INTCHW_INTC1_DMPU_BITNUM 17 /* DDR2 memory partition interrupt */
125#define INTCHW_INTC1_KEYC_BITNUM 16 /* Key pad controller interrupt */
126#define INTCHW_INTC1_TSC_BITNUM 15 /* Touch screen controller interrupt */
127#define INTCHW_INTC1_UART0_BITNUM 14 /* UART 0 */
128#define INTCHW_INTC1_WDOG_BITNUM 13 /* Watchdog timer interrupt */
129
130#define INTCHW_INTC1_UART1_BITNUM 12 /* UART 1 */
131#define INTCHW_INTC1_PMUIRQ_BITNUM 11 /* ARM performance monitor interrupt */
132#define INTCHW_INTC1_COMMRX_BITNUM 10 /* ARM DDC receive interrupt */
133#define INTCHW_INTC1_COMMTX_BITNUM 9 /* ARM DDC transmit interrupt */
134#define INTCHW_INTC1_FLASHC_BITNUM 8 /* Flash controller interrupt */
135#define INTCHW_INTC1_GPHY_BITNUM 7 /* Gigabit Phy interrupt */
136#define INTCHW_INTC1_SPIS_BITNUM 6 /* SPI slave interrupt */
137#define INTCHW_INTC1_I2CS_BITNUM 5 /* I2C slave interrupt */
138#define INTCHW_INTC1_I2CH_BITNUM 4 /* I2C host interrupt */
139#define INTCHW_INTC1_I2S1_BITNUM 3 /* I2S1 interrupt */
140#define INTCHW_INTC1_I2S0_BITNUM 2 /* I2S0 interrupt */
141#define INTCHW_INTC1_GPIO1_BITNUM 1 /* GPIO bit 64//32 combined interrupt */
142#define INTCHW_INTC1_GPIO0_BITNUM 0 /* GPIO bit 31//0 combined interrupt */
143
144#define INTCHW_INTC1_DDRVPMT (1<<INTCHW_INTC1_DDRVPMT_BITNUM)
145#define INTCHW_INTC1_DDRVPMP (1<<INTCHW_INTC1_DDRVPMP_BITNUM)
146#define INTCHW_INTC1_DDRP (1<<INTCHW_INTC1_DDRP_BITNUM)
147#define INTCHW_INTC1_VDEC (1<<INTCHW_INTC1_VDEC_BITNUM)
148#define INTCHW_INTC1_SPUM (1<<INTCHW_INTC1_SPUM_BITNUM)
149#define INTCHW_INTC1_RTC2 (1<<INTCHW_INTC1_RTC2_BITNUM)
150#define INTCHW_INTC1_RTC1 (1<<INTCHW_INTC1_RTC1_BITNUM)
151#define INTCHW_INTC1_RTC0 (1<<INTCHW_INTC1_RTC0_BITNUM)
152#define INTCHW_INTC1_RNG (1<<INTCHW_INTC1_RNG_BITNUM)
153#define INTCHW_INTC1_FMPU (1<<INTCHW_INTC1_FMPU_BITNUM)
154#define INTCHW_INTC1_IMPU (1<<INTCHW_INTC1_IMPU_BITNUM)
155#define INTCHW_INTC1_DMPU (1<<INTCHW_INTC1_DMPU_BITNUM)
156#define INTCHW_INTC1_KEYC (1<<INTCHW_INTC1_KEYC_BITNUM)
157#define INTCHW_INTC1_TSC (1<<INTCHW_INTC1_TSC_BITNUM)
158#define INTCHW_INTC1_UART0 (1<<INTCHW_INTC1_UART0_BITNUM)
159#define INTCHW_INTC1_WDOG (1<<INTCHW_INTC1_WDOG_BITNUM)
160#define INTCHW_INTC1_UART1 (1<<INTCHW_INTC1_UART1_BITNUM)
161#define INTCHW_INTC1_PMUIRQ (1<<INTCHW_INTC1_PMUIRQ_BITNUM)
162#define INTCHW_INTC1_COMMRX (1<<INTCHW_INTC1_COMMRX_BITNUM)
163#define INTCHW_INTC1_COMMTX (1<<INTCHW_INTC1_COMMTX_BITNUM)
164#define INTCHW_INTC1_FLASHC (1<<INTCHW_INTC1_FLASHC_BITNUM)
165#define INTCHW_INTC1_GPHY (1<<INTCHW_INTC1_GPHY_BITNUM)
166#define INTCHW_INTC1_SPIS (1<<INTCHW_INTC1_SPIS_BITNUM)
167#define INTCHW_INTC1_I2CS (1<<INTCHW_INTC1_I2CS_BITNUM)
168#define INTCHW_INTC1_I2CH (1<<INTCHW_INTC1_I2CH_BITNUM)
169#define INTCHW_INTC1_I2S1 (1<<INTCHW_INTC1_I2S1_BITNUM)
170#define INTCHW_INTC1_I2S0 (1<<INTCHW_INTC1_I2S0_BITNUM)
171#define INTCHW_INTC1_GPIO1 (1<<INTCHW_INTC1_GPIO1_BITNUM)
172#define INTCHW_INTC1_GPIO0 (1<<INTCHW_INTC1_GPIO0_BITNUM)
173
174/* SINTC secure int controller */
175#define INTCHW_SINTC_RTC2_BITNUM 15 /* Real time clock tamper interrupt */
176#define INTCHW_SINTC_TIMER3_BITNUM 14 /* Secure timer3 interrupt */
177#define INTCHW_SINTC_TIMER2_BITNUM 13 /* Secure timer2 interrupt */
178#define INTCHW_SINTC_TIMER1_BITNUM 12 /* Secure timer1 interrupt */
179#define INTCHW_SINTC_TIMER0_BITNUM 11 /* Secure timer0 interrupt */
180#define INTCHW_SINTC_SPUM_BITNUM 10 /* Secure process module interrupt */
181#define INTCHW_SINTC_RTC1_BITNUM 9 /* Real time clock one-shot interrupt */
182#define INTCHW_SINTC_RTC0_BITNUM 8 /* Real time clock periodic interrupt */
183#define INTCHW_SINTC_RNG_BITNUM 7 /* Random number generator interrupt */
184#define INTCHW_SINTC_FMPU_BITNUM 6 /* Flash memory parition unit interrupt */
185#define INTCHW_SINTC_VMPU_BITNUM 5 /* VRAM memory partition interrupt */
186#define INTCHW_SINTC_DMPU_BITNUM 4 /* DDR2 memory partition interrupt */
187#define INTCHW_SINTC_KEYC_BITNUM 3 /* Key pad controller interrupt */
188#define INTCHW_SINTC_TSC_BITNUM 2 /* Touch screen controller interrupt */
189#define INTCHW_SINTC_UART0_BITNUM 1 /* UART0 interrupt */
190#define INTCHW_SINTC_WDOG_BITNUM 0 /* Watchdog timer interrupt */
191
192#define INTCHW_SINTC_TIMER3 (1<<INTCHW_SINTC_TIMER3_BITNUM)
193#define INTCHW_SINTC_TIMER2 (1<<INTCHW_SINTC_TIMER2_BITNUM)
194#define INTCHW_SINTC_TIMER1 (1<<INTCHW_SINTC_TIMER1_BITNUM)
195#define INTCHW_SINTC_TIMER0 (1<<INTCHW_SINTC_TIMER0_BITNUM)
196#define INTCHW_SINTC_SPUM (1<<INTCHW_SINTC_SPUM_BITNUM)
197#define INTCHW_SINTC_RTC2 (1<<INTCHW_SINTC_RTC2_BITNUM)
198#define INTCHW_SINTC_RTC1 (1<<INTCHW_SINTC_RTC1_BITNUM)
199#define INTCHW_SINTC_RTC0 (1<<INTCHW_SINTC_RTC0_BITNUM)
200#define INTCHW_SINTC_RNG (1<<INTCHW_SINTC_RNG_BITNUM)
201#define INTCHW_SINTC_FMPU (1<<INTCHW_SINTC_FMPU_BITNUM)
202#define INTCHW_SINTC_IMPU (1<<INTCHW_SINTC_IMPU_BITNUM)
203#define INTCHW_SINTC_DMPU (1<<INTCHW_SINTC_DMPU_BITNUM)
204#define INTCHW_SINTC_KEYC (1<<INTCHW_SINTC_KEYC_BITNUM)
205#define INTCHW_SINTC_TSC (1<<INTCHW_SINTC_TSC_BITNUM)
206#define INTCHW_SINTC_UART0 (1<<INTCHW_SINTC_UART0_BITNUM)
207#define INTCHW_SINTC_WDOG (1<<INTCHW_SINTC_WDOG_BITNUM)
208
209/* PL192 Vectored Interrupt Controller (VIC) layout */
210#define INTCHW_IRQSTATUS 0x00 /* IRQ status register */
211#define INTCHW_FIQSTATUS 0x04 /* FIQ status register */
212#define INTCHW_RAWINTR 0x08 /* Raw Interrupt Status register */
213#define INTCHW_INTSELECT 0x0c /* Interrupt Select Register */
214#define INTCHW_INTENABLE 0x10 /* Interrupt Enable Register */
215#define INTCHW_INTENCLEAR 0x14 /* Interrupt Enable Clear Register */
216#define INTCHW_SOFTINT 0x18 /* Soft Interrupt Register */
217#define INTCHW_SOFTINTCLEAR 0x1c /* Soft Interrupt Clear Register */
218#define INTCHW_PROTECTION 0x20 /* Protection Enable Register */
219#define INTCHW_SWPRIOMASK 0x24 /* Software Priority Mask Register */
220#define INTCHW_PRIODAISY 0x28 /* Priority Daisy Chain Register */
221#define INTCHW_VECTADDR0 0x100 /* Vector Address Registers */
222#define INTCHW_VECTPRIO0 0x200 /* Vector Priority Registers 0-31 */
223#define INTCHW_ADDRESS 0xf00 /* Vector Address Register 0-31 */
224#define INTCHW_PID 0xfe0 /* Peripheral ID Register 0-3 */
225#define INTCHW_PCELLID 0xff0 /* PrimeCell ID Register 0-3 */
226
227/* Example Usage: intcHw_irq_enable(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */
228/* intcHw_irq_clear(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */
229/* uint32_t bits = intcHw_irq_status(INTCHW_INTC0); */
230/* uint32_t bits = intcHw_irq_raw_status(INTCHW_INTC0); */
231
232/* ---- Public Variable Externs ------------------------------------------ */
233/* ---- Public Function Prototypes --------------------------------------- */
234/* Clear one or more IRQ interrupts. */
235static inline void intcHw_irq_disable(void *basep, uint32_t mask)
236{
237 __REG32(basep + INTCHW_INTENCLEAR) = mask;
238}
239
240/* Enables one or more IRQ interrupts. */
241static inline void intcHw_irq_enable(void *basep, uint32_t mask)
242{
243 __REG32(basep + INTCHW_INTENABLE) = mask;
244}
245
246#endif /* _INTCHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
new file mode 100644
index 000000000000..86bb58d4f58c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
@@ -0,0 +1,101 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file mm_addr.h
18*
19* @brief Memory Map address defintions
20*
21* @note
22* None
23*/
24/****************************************************************************/
25
26#ifndef _MM_ADDR_H
27#define _MM_ADDR_H
28
29/* ---- Include Files ---------------------------------------------------- */
30
31#if !defined(CSP_SIMULATION)
32#include <cfg_global.h>
33#endif
34
35/* ---- Public Constants and Types --------------------------------------- */
36
37/* Memory Map address definitions */
38
39#define MM_ADDR_DDR 0x00000000
40
41#define MM_ADDR_IO_VPM_EXTMEM_RSVD 0x0F000000 /* 16 MB - Reserved external memory for VPM use */
42
43#define MM_ADDR_IO_FLASHC 0x20000000
44#define MM_ADDR_IO_BROM 0x30000000
45#define MM_ADDR_IO_ARAM 0x30100000 /* 64 KB - extra cycle latency - WS switch */
46#define MM_ADDR_IO_DMA0 0x30200000
47#define MM_ADDR_IO_DMA1 0x30300000
48#define MM_ADDR_IO_ESW 0x30400000
49#define MM_ADDR_IO_CLCD 0x30500000
50#define MM_ADDR_IO_PIF 0x30580000
51#define MM_ADDR_IO_APM 0x30600000
52#define MM_ADDR_IO_SPUM 0x30700000
53#define MM_ADDR_IO_VPM_PROG 0x30800000
54#define MM_ADDR_IO_VPM_DATA 0x30A00000
55#define MM_ADDR_IO_VRAM 0x40000000 /* 64 KB - security block in front of it */
56#define MM_ADDR_IO_CHIPC 0x80000000
57#define MM_ADDR_IO_UMI 0x80001000
58#define MM_ADDR_IO_NAND 0x80001800
59#define MM_ADDR_IO_LEDM 0x80002000
60#define MM_ADDR_IO_PWM 0x80002040
61#define MM_ADDR_IO_VINTC 0x80003000
62#define MM_ADDR_IO_GPIO0 0x80004000
63#define MM_ADDR_IO_GPIO1 0x80004800
64#define MM_ADDR_IO_I2CS 0x80005000
65#define MM_ADDR_IO_SPIS 0x80006000
66#define MM_ADDR_IO_HPM 0x80007400
67#define MM_ADDR_IO_HPM_REMAP 0x80007800
68#define MM_ADDR_IO_TZPC 0x80008000
69#define MM_ADDR_IO_MPU 0x80009000
70#define MM_ADDR_IO_SPUMP 0x8000a000
71#define MM_ADDR_IO_PKA 0x8000b000
72#define MM_ADDR_IO_RNG 0x8000c000
73#define MM_ADDR_IO_KEYC 0x8000d000
74#define MM_ADDR_IO_BBL 0x8000e000
75#define MM_ADDR_IO_OTP 0x8000f000
76#define MM_ADDR_IO_I2S0 0x80010000
77#define MM_ADDR_IO_I2S1 0x80011000
78#define MM_ADDR_IO_UARTA 0x80012000
79#define MM_ADDR_IO_UARTB 0x80013000
80#define MM_ADDR_IO_I2CH 0x80014020
81#define MM_ADDR_IO_SPIH 0x80015000
82#define MM_ADDR_IO_TSC 0x80016000
83#define MM_ADDR_IO_TMR 0x80017000
84#define MM_ADDR_IO_WATCHDOG 0x80017800
85#define MM_ADDR_IO_ETM 0x80018000
86#define MM_ADDR_IO_DDRC 0x80019000
87#define MM_ADDR_IO_SINTC 0x80100000
88#define MM_ADDR_IO_INTC0 0x80200000
89#define MM_ADDR_IO_INTC1 0x80201000
90#define MM_ADDR_IO_GE 0x80300000
91#define MM_ADDR_IO_USB_CTLR0 0x80400000
92#define MM_ADDR_IO_USB_CTLR1 0x80410000
93#define MM_ADDR_IO_USB_PHY 0x80420000
94#define MM_ADDR_IO_SDIOH0 0x80500000
95#define MM_ADDR_IO_SDIOH1 0x80600000
96#define MM_ADDR_IO_VDEC 0x80700000
97
98/* ---- Public Variable Externs ------------------------------------------ */
99/* ---- Public Function Prototypes --------------------------------------- */
100
101#endif /* _MM_ADDR_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_io.h b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h
new file mode 100644
index 000000000000..de92ec6a01aa
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h
@@ -0,0 +1,147 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file mm_io.h
18*
19* @brief Memory Map I/O definitions
20*
21* @note
22* None
23*/
24/****************************************************************************/
25
26#ifndef _MM_IO_H
27#define _MM_IO_H
28
29/* ---- Include Files ---------------------------------------------------- */
30#include <mach/csp/mm_addr.h>
31
32#if !defined(CSP_SIMULATION)
33#include <cfg_global.h>
34#endif
35
36/* ---- Public Constants and Types --------------------------------------- */
37
38#if defined(CONFIG_MMU)
39
40/* This macro is referenced in <mach/io.h>
41 * Phys to Virtual 0xNyxxxxxx => 0xFNxxxxxx
42 * This macro is referenced in <asm/arch/io.h>
43 *
44 * Assume VPM address is the last x MB of memory. For VPM, map to
45 * 0xf0000000 and up.
46 */
47
48#ifndef MM_IO_PHYS_TO_VIRT
49#ifdef __ASSEMBLY__
50#define MM_IO_PHYS_TO_VIRT(phys) (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF))
51#else
52#define MM_IO_PHYS_TO_VIRT(phys) (((phys) == MM_ADDR_IO_VPM_EXTMEM_RSVD) ? 0xF0000000 : \
53 (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF)))
54#endif
55#endif
56
57/* Virtual to Physical 0xFNxxxxxx => 0xN0xxxxxx */
58
59#ifndef MM_IO_VIRT_TO_PHYS
60#ifdef __ASSEMBLY__
61#define MM_IO_VIRT_TO_PHYS(virt) ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF))
62#else
63#define MM_IO_VIRT_TO_PHYS(virt) (((virt) == 0xF0000000) ? MM_ADDR_IO_VPM_EXTMEM_RSVD : \
64 ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF)))
65#endif
66#endif
67
68#else
69
70#ifndef MM_IO_PHYS_TO_VIRT
71#define MM_IO_PHYS_TO_VIRT(phys) (phys)
72#endif
73
74#ifndef MM_IO_VIRT_TO_PHYS
75#define MM_IO_VIRT_TO_PHYS(virt) (virt)
76#endif
77
78#endif
79
80/* Registers in 0xExxxxxxx that should be moved to 0xFxxxxxxx */
81#define MM_IO_BASE_FLASHC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_FLASHC)
82#define MM_IO_BASE_NAND MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_NAND)
83#define MM_IO_BASE_UMI MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UMI)
84
85#define MM_IO_START MM_ADDR_IO_FLASHC /* Physical beginning of IO mapped memory */
86#define MM_IO_BASE MM_IO_BASE_FLASHC /* Virtual beginning of IO mapped memory */
87
88#define MM_IO_BASE_BROM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BROM)
89#define MM_IO_BASE_ARAM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ARAM)
90#define MM_IO_BASE_DMA0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA0)
91#define MM_IO_BASE_DMA1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA1)
92#define MM_IO_BASE_ESW MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ESW)
93#define MM_IO_BASE_CLCD MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CLCD)
94#define MM_IO_BASE_PIF MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PIF)
95#define MM_IO_BASE_APM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_APM)
96#define MM_IO_BASE_SPUM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUM)
97#define MM_IO_BASE_VPM_PROG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_PROG)
98#define MM_IO_BASE_VPM_DATA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_DATA)
99
100#define MM_IO_BASE_VRAM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VRAM)
101
102#define MM_IO_BASE_CHIPC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CHIPC)
103#define MM_IO_BASE_DDRC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DDRC)
104#define MM_IO_BASE_LEDM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_LEDM)
105#define MM_IO_BASE_PWM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PWM)
106#define MM_IO_BASE_VINTC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VINTC)
107#define MM_IO_BASE_GPIO0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO0)
108#define MM_IO_BASE_GPIO1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO1)
109#define MM_IO_BASE_TMR MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TMR)
110#define MM_IO_BASE_WATCHDOG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_WATCHDOG)
111#define MM_IO_BASE_ETM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ETM)
112#define MM_IO_BASE_HPM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM)
113#define MM_IO_BASE_HPM_REMAP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM_REMAP)
114#define MM_IO_BASE_TZPC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TZPC)
115#define MM_IO_BASE_MPU MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_MPU)
116#define MM_IO_BASE_SPUMP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUMP)
117#define MM_IO_BASE_PKA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PKA)
118#define MM_IO_BASE_RNG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_RNG)
119#define MM_IO_BASE_KEYC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_KEYC)
120#define MM_IO_BASE_BBL MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BBL)
121#define MM_IO_BASE_OTP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_OTP)
122#define MM_IO_BASE_I2S0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S0)
123#define MM_IO_BASE_I2S1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S1)
124#define MM_IO_BASE_UARTA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTA)
125#define MM_IO_BASE_UARTB MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTB)
126#define MM_IO_BASE_I2CH MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CH)
127#define MM_IO_BASE_SPIH MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIH)
128#define MM_IO_BASE_TSC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TSC)
129#define MM_IO_BASE_I2CS MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CS)
130#define MM_IO_BASE_SPIS MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIS)
131#define MM_IO_BASE_SINTC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SINTC)
132#define MM_IO_BASE_INTC0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC0)
133#define MM_IO_BASE_INTC1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC1)
134#define MM_IO_BASE_GE MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GE)
135#define MM_IO_BASE_USB_CTLR0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR0)
136#define MM_IO_BASE_USB_CTLR1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR1)
137#define MM_IO_BASE_USB_PHY MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_PHY)
138#define MM_IO_BASE_SDIOH0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH0)
139#define MM_IO_BASE_SDIOH1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH1)
140#define MM_IO_BASE_VDEC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VDEC)
141
142#define MM_IO_BASE_VPM_EXTMEM_RSVD MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_EXTMEM_RSVD)
143
144/* ---- Public Variable Externs ------------------------------------------ */
145/* ---- Public Function Prototypes --------------------------------------- */
146
147#endif /* _MM_IO_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h
new file mode 100644
index 000000000000..d15f5f3ec2d8
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h
@@ -0,0 +1,100 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file secHw_def.h
18*
19* @brief Definitions for configuring/testing secure blocks
20*
21* @note
22* None
23*/
24/****************************************************************************/
25
26#ifndef SECHW_DEF_H
27#define SECHW_DEF_H
28
29#include <mach/csp/mm_io.h>
30
31/* Bit mask for various secure device */
32#define secHw_BLK_MASK_CHIP_CONTROL 0x00000001
33#define secHw_BLK_MASK_KEY_SCAN 0x00000002
34#define secHw_BLK_MASK_TOUCH_SCREEN 0x00000004
35#define secHw_BLK_MASK_UART0 0x00000008
36#define secHw_BLK_MASK_UART1 0x00000010
37#define secHw_BLK_MASK_WATCHDOG 0x00000020
38#define secHw_BLK_MASK_SPUM 0x00000040
39#define secHw_BLK_MASK_DDR2 0x00000080
40#define secHw_BLK_MASK_EXT_MEM 0x00000100
41#define secHw_BLK_MASK_ESW 0x00000200
42#define secHw_BLK_MASK_SPU 0x00010000
43#define secHw_BLK_MASK_PKA 0x00020000
44#define secHw_BLK_MASK_RNG 0x00040000
45#define secHw_BLK_MASK_RTC 0x00080000
46#define secHw_BLK_MASK_OTP 0x00100000
47#define secHw_BLK_MASK_BOOT 0x00200000
48#define secHw_BLK_MASK_MPU 0x00400000
49#define secHw_BLK_MASK_TZCTRL 0x00800000
50#define secHw_BLK_MASK_INTR 0x01000000
51
52/* Trustzone register set */
53typedef struct {
54 volatile uint32_t status; /* read only - reflects status of writes of 2 write registers */
55 volatile uint32_t setUnsecure; /* write only. reads back as 0 */
56 volatile uint32_t setSecure; /* write only. reads back as 0 */
57} secHw_TZREG_t;
58
59/* There are 2 register sets. The first is for the lower 16 bits, the 2nd */
60/* is for the higher 16 bits. */
61
62typedef enum {
63 secHw_IDX_LS = 0,
64 secHw_IDX_MS = 1,
65 secHw_IDX_NUM
66} secHw_IDX_e;
67
68typedef struct {
69 volatile secHw_TZREG_t reg[secHw_IDX_NUM];
70} secHw_REGS_t;
71
72/****************************************************************************/
73/**
74* @brief Configures a device as a secure device
75*
76*/
77/****************************************************************************/
78static inline void secHw_setSecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
79 );
80
81/****************************************************************************/
82/**
83* @brief Configures a device as a non-secure device
84*
85*/
86/****************************************************************************/
87static inline void secHw_setUnsecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
88 );
89
90/****************************************************************************/
91/**
92* @brief Get the trustzone status for all components. 1 = non-secure, 0 = secure
93*
94*/
95/****************************************************************************/
96static inline uint32_t secHw_getStatus(void);
97
98#include <mach/csp/secHw_inline.h>
99
100#endif /* SECHW_DEF_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h
new file mode 100644
index 000000000000..9cd6a032ab71
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h
@@ -0,0 +1,79 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file secHw_inline.h
18*
19* @brief Definitions for configuring/testing secure blocks
20*
21* @note
22* None
23*/
24/****************************************************************************/
25
26#ifndef SECHW_INLINE_H
27#define SECHW_INLINE_H
28
29/****************************************************************************/
30/**
31* @brief Configures a device as a secure device
32*
33*/
34/****************************************************************************/
35static inline void secHw_setSecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
36 ) {
37 secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
38
39 if (mask & 0x0000FFFF) {
40 regp->reg[secHw_IDX_LS].setSecure = mask & 0x0000FFFF;
41 }
42
43 if (mask & 0xFFFF0000) {
44 regp->reg[secHw_IDX_MS].setSecure = mask >> 16;
45 }
46}
47
48/****************************************************************************/
49/**
50* @brief Configures a device as a non-secure device
51*
52*/
53/****************************************************************************/
54static inline void secHw_setUnsecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
55 ) {
56 secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
57
58 if (mask & 0x0000FFFF) {
59 regp->reg[secHw_IDX_LS].setUnsecure = mask & 0x0000FFFF;
60 }
61 if (mask & 0xFFFF0000) {
62 regp->reg[secHw_IDX_MS].setUnsecure = mask >> 16;
63 }
64}
65
66/****************************************************************************/
67/**
68* @brief Get the trustzone status for all components. 1 = non-secure, 0 = secure
69*
70*/
71/****************************************************************************/
72static inline uint32_t secHw_getStatus(void)
73{
74 secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
75
76 return (regp->reg[1].status << 16) + regp->reg[0].status;
77}
78
79#endif /* SECHW_INLINE_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h
new file mode 100644
index 000000000000..3080ac7239a1
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h
@@ -0,0 +1,82 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file tmrHw_reg.h
18*
19* @brief Definitions for low level Timer registers
20*
21*/
22/****************************************************************************/
23#ifndef _TMRHW_REG_H
24#define _TMRHW_REG_H
25
26#include <mach/csp/mm_io.h>
27#include <mach/csp/hw_cfg.h>
28/* Base address */
29#define tmrHw_MODULE_BASE_ADDR MM_IO_BASE_TMR
30
31/*
32This platform has four different timers running at different clock speed
33
34Timer one (Timer ID 0) runs at 25 MHz
35Timer two (Timer ID 1) runs at 25 MHz
36Timer three (Timer ID 2) runs at 150 MHz
37Timer four (Timer ID 3) runs at 150 MHz
38*/
39#define tmrHw_LOW_FREQUENCY_MHZ 25 /* Always 25MHz from XTAL */
40#define tmrHw_LOW_FREQUENCY_HZ 25000000
41
42#if defined(CFG_GLOBAL_CHIP) && (CFG_GLOBAL_CHIP == FPGA11107)
43#define tmrHw_HIGH_FREQUENCY_MHZ 150 /* Always 150MHz for FPGA */
44#define tmrHw_HIGH_FREQUENCY_HZ 150000000
45#else
46#define tmrHw_HIGH_FREQUENCY_HZ HW_CFG_BUS_CLK_HZ
47#define tmrHw_HIGH_FREQUENCY_MHZ (HW_CFG_BUS_CLK_HZ / 1000000)
48#endif
49
50#define tmrHw_LOW_RESOLUTION_CLOCK tmrHw_LOW_FREQUENCY_HZ
51#define tmrHw_HIGH_RESOLUTION_CLOCK tmrHw_HIGH_FREQUENCY_HZ
52#define tmrHw_MAX_COUNT (0xFFFFFFFF) /* maximum number of count a timer can count */
53#define tmrHw_TIMER_NUM_COUNT (4) /* Number of timer module supported */
54
55typedef struct {
56 uint32_t LoadValue; /* Load value for timer */
57 uint32_t CurrentValue; /* Current value for timer */
58 uint32_t Control; /* Control register */
59 uint32_t InterruptClear; /* Interrupt clear register */
60 uint32_t RawInterruptStatus; /* Raw interrupt status */
61 uint32_t InterruptStatus; /* Masked interrupt status */
62 uint32_t BackgroundLoad; /* Background load value */
63 uint32_t padding; /* Padding register */
64} tmrHw_REG_t;
65
66/* Control bot masks */
67#define tmrHw_CONTROL_TIMER_ENABLE 0x00000080
68#define tmrHw_CONTROL_PERIODIC 0x00000040
69#define tmrHw_CONTROL_INTERRUPT_ENABLE 0x00000020
70#define tmrHw_CONTROL_PRESCALE_MASK 0x0000000C
71#define tmrHw_CONTROL_PRESCALE_1 0x00000000
72#define tmrHw_CONTROL_PRESCALE_16 0x00000004
73#define tmrHw_CONTROL_PRESCALE_256 0x00000008
74#define tmrHw_CONTROL_32BIT 0x00000002
75#define tmrHw_CONTROL_ONESHOT 0x00000001
76#define tmrHw_CONTROL_FREE_RUNNING 0x00000000
77
78#define tmrHw_CONTROL_MODE_MASK (tmrHw_CONTROL_PERIODIC | tmrHw_CONTROL_ONESHOT)
79
80#define pTmrHw ((volatile tmrHw_REG_t *)tmrHw_MODULE_BASE_ADDR)
81
82#endif /* _TMRHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h
new file mode 100644
index 000000000000..847980c85c88
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/dma.h
@@ -0,0 +1,826 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/****************************************************************************/
16/**
17* @file dma.h
18*
19* @brief API definitions for the linux DMA interface.
20*/
21/****************************************************************************/
22
23#if !defined(ASM_ARM_ARCH_BCMRING_DMA_H)
24#define ASM_ARM_ARCH_BCMRING_DMA_H
25
26/* ---- Include Files ---------------------------------------------------- */
27
28#include <linux/kernel.h>
29#include <linux/wait.h>
30#include <linux/semaphore.h>
31#include <csp/dmacHw.h>
32#include <mach/timer.h>
33#include <linux/scatterlist.h>
34#include <linux/dma-mapping.h>
35#include <linux/mm.h>
36#include <linux/vmalloc.h>
37#include <linux/pagemap.h>
38
39/* ---- Constants and Types ---------------------------------------------- */
40
41/* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */
42/* and line number of the reservation request will be recorded in the channel table */
43
44#define DMA_DEBUG_TRACK_RESERVATION 1
45
46#define DMA_NUM_CONTROLLERS 2
47#define DMA_NUM_CHANNELS 8 /* per controller */
48
49typedef enum {
50 DMA_DEVICE_MEM_TO_MEM, /* For memory to memory transfers */
51 DMA_DEVICE_I2S0_DEV_TO_MEM,
52 DMA_DEVICE_I2S0_MEM_TO_DEV,
53 DMA_DEVICE_I2S1_DEV_TO_MEM,
54 DMA_DEVICE_I2S1_MEM_TO_DEV,
55 DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM,
56 DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV,
57 DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM,
58 DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV,
59 DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM, /* Additional mic input for beam-forming */
60 DMA_DEVICE_APM_PCM0_DEV_TO_MEM,
61 DMA_DEVICE_APM_PCM0_MEM_TO_DEV,
62 DMA_DEVICE_APM_PCM1_DEV_TO_MEM,
63 DMA_DEVICE_APM_PCM1_MEM_TO_DEV,
64 DMA_DEVICE_SPUM_DEV_TO_MEM,
65 DMA_DEVICE_SPUM_MEM_TO_DEV,
66 DMA_DEVICE_SPIH_DEV_TO_MEM,
67 DMA_DEVICE_SPIH_MEM_TO_DEV,
68 DMA_DEVICE_UART_A_DEV_TO_MEM,
69 DMA_DEVICE_UART_A_MEM_TO_DEV,
70 DMA_DEVICE_UART_B_DEV_TO_MEM,
71 DMA_DEVICE_UART_B_MEM_TO_DEV,
72 DMA_DEVICE_PIF_MEM_TO_DEV,
73 DMA_DEVICE_PIF_DEV_TO_MEM,
74 DMA_DEVICE_ESW_DEV_TO_MEM,
75 DMA_DEVICE_ESW_MEM_TO_DEV,
76 DMA_DEVICE_VPM_MEM_TO_MEM,
77 DMA_DEVICE_CLCD_MEM_TO_MEM,
78 DMA_DEVICE_NAND_MEM_TO_MEM,
79 DMA_DEVICE_MEM_TO_VRAM,
80 DMA_DEVICE_VRAM_TO_MEM,
81
82 /* Add new entries before this line. */
83
84 DMA_NUM_DEVICE_ENTRIES,
85 DMA_DEVICE_NONE = 0xff, /* Special value to indicate that no device is currently assigned. */
86
87} DMA_Device_t;
88
89/****************************************************************************
90*
91* The DMA_Handle_t is the primary object used by callers of the API.
92*
93*****************************************************************************/
94
95#define DMA_INVALID_HANDLE ((DMA_Handle_t) -1)
96
97typedef int DMA_Handle_t;
98
99/****************************************************************************
100*
101* The DMA_DescriptorRing_t contains a ring of descriptors which is used
102* to point to regions of memory.
103*
104*****************************************************************************/
105
106typedef struct {
107 void *virtAddr; /* Virtual Address of the descriptor ring */
108 dma_addr_t physAddr; /* Physical address of the descriptor ring */
109 int descriptorsAllocated; /* Number of descriptors allocated in the descriptor ring */
110 size_t bytesAllocated; /* Number of bytes allocated in the descriptor ring */
111
112} DMA_DescriptorRing_t;
113
114/****************************************************************************
115*
116* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup
117* DMA chains from a variety of memory sources.
118*
119*****************************************************************************/
120
121#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */
122 /* off not being DMA'd. */
123
124typedef enum {
125 DMA_MEM_TYPE_NONE, /* Not a valid setting */
126 DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */
127 DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */
128 DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */
129 DMA_MEM_TYPE_USER, /* Memory came from user space. */
130
131} DMA_MemType_t;
132
133/* A segment represents a physically and virtually contiguous chunk of memory. */
134/* i.e. each segment can be DMA'd */
135/* A user of the DMA code will add memory regions. Each region may need to be */
136/* represented by one or more segments. */
137
138typedef struct {
139 void *virtAddr; /* Virtual address used for this segment */
140 dma_addr_t physAddr; /* Physical address this segment maps to */
141 size_t numBytes; /* Size of the segment, in bytes */
142
143} DMA_Segment_t;
144
145/* A region represents a virtually contiguous chunk of memory, which may be */
146/* made up of multiple segments. */
147
148typedef struct {
149 DMA_MemType_t memType;
150 void *virtAddr;
151 size_t numBytes;
152
153 /* Each region (virtually contiguous) consists of one or more segments. Each */
154 /* segment is virtually and physically contiguous. */
155
156 int numSegmentsUsed;
157 int numSegmentsAllocated;
158 DMA_Segment_t *segment;
159
160 /* When a region corresponds to user memory, we need to lock all of the pages */
161 /* down before we can figure out the physical addresses. The lockedPage array contains */
162 /* the pages that were locked, and which subsequently need to be unlocked once the */
163 /* memory is unmapped. */
164
165 unsigned numLockedPages;
166 struct page **lockedPages;
167
168} DMA_Region_t;
169
170typedef struct {
171 int inUse; /* Is this mapping currently being used? */
172 struct semaphore lock; /* Acquired when using this structure */
173 enum dma_data_direction dir; /* Direction this transfer is intended for */
174
175 /* In the event that we're mapping user memory, we need to know which task */
176 /* the memory is for, so that we can obtain the correct mm locks. */
177
178 struct task_struct *userTask;
179
180 int numRegionsUsed;
181 int numRegionsAllocated;
182 DMA_Region_t *region;
183
184} DMA_MemMap_t;
185
186/****************************************************************************
187*
188* The DMA_DeviceAttribute_t contains information which describes a
189* particular DMA device (or peripheral).
190*
191* It is anticipated that the arrary of DMA_DeviceAttribute_t's will be
192* statically initialized.
193*
194*****************************************************************************/
195
196/* The device handler is called whenever a DMA operation completes. The reaon */
197/* for it to be called will be a bitmask with one or more of the following bits */
198/* set. */
199
200#define DMA_HANDLER_REASON_BLOCK_COMPLETE dmacHw_INTERRUPT_STATUS_BLOCK
201#define DMA_HANDLER_REASON_TRANSFER_COMPLETE dmacHw_INTERRUPT_STATUS_TRANS
202#define DMA_HANDLER_REASON_ERROR dmacHw_INTERRUPT_STATUS_ERROR
203
204typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason,
205 void *userData);
206
207#define DMA_DEVICE_FLAG_ON_DMA0 0x00000001
208#define DMA_DEVICE_FLAG_ON_DMA1 0x00000002
209#define DMA_DEVICE_FLAG_PORT_PER_DMAC 0x00000004 /* If set, it means that the port used on DMAC0 is different from the port used on DMAC1 */
210#define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST 0x00000008 /* If set, allocate from DMA1 before allocating from DMA0 */
211#define DMA_DEVICE_FLAG_IS_DEDICATED 0x00000100
212#define DMA_DEVICE_FLAG_NO_ISR 0x00000200
213#define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO 0x00000400
214#define DMA_DEVICE_FLAG_IN_USE 0x00000800 /* If set, device is in use on a channel */
215
216/* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */
217/* determine which DMA controllers a given device can be used from, and the interface */
218/* array determeines the actual interface number to use for a given controller. */
219
220typedef struct {
221 uint32_t flags; /* Bitmask of DMA_DEVICE_FLAG_xxx constants */
222 uint8_t dedicatedController; /* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */
223 uint8_t dedicatedChannel; /* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */
224 const char *name; /* Will show up in the /proc entry */
225
226 uint32_t dmacPort[DMA_NUM_CONTROLLERS]; /* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */
227
228 dmacHw_CONFIG_t config; /* Configuration to use when DMA'ing using this device */
229
230 void *userData; /* Passed to the devHandler */
231 DMA_DeviceHandler_t devHandler; /* Called when DMA operations finish. */
232
233 timer_tick_count_t transferStartTime; /* Time the current transfer was started */
234
235 /* The following statistical information will be collected and presented in a proc entry. */
236 /* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */
237 /* a 64 bit counter. */
238
239 uint64_t numTransfers; /* Number of DMA transfers performed */
240 uint64_t transferTicks; /* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */
241 uint64_t transferBytes; /* Total bytes transferred */
242 uint32_t timesBlocked; /* Number of times a channel was unavailable */
243 uint32_t numBytes; /* Last transfer size */
244
245 /* It's not possible to free memory which is allocated for the descriptors from within */
246 /* the ISR. So make the presumption that a given device will tend to use the */
247 /* same sized buffers over and over again, and we keep them around. */
248
249 DMA_DescriptorRing_t ring; /* Ring of descriptors allocated for this device */
250
251 /* We stash away some of the information from the previous transfer. If back-to-back */
252 /* transfers are performed from the same buffer, then we don't have to keep re-initializing */
253 /* the descriptor buffers. */
254
255 uint32_t prevNumBytes;
256 dma_addr_t prevSrcData;
257 dma_addr_t prevDstData;
258
259} DMA_DeviceAttribute_t;
260
261/****************************************************************************
262*
263* DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal
264* data structures and don't belong in this header file, but are included
265* merely for discussion.
266*
267* By the time this is implemented, these structures will be moved out into
268* the appropriate C source file instead.
269*
270*****************************************************************************/
271
272/****************************************************************************
273*
274* The DMA_Channel_t contains state information about each DMA channel. Some
275* of the channels are dedicated. Non-dedicated channels are shared
276* amongst the other devices.
277*
278*****************************************************************************/
279
280#define DMA_CHANNEL_FLAG_IN_USE 0x00000001
281#define DMA_CHANNEL_FLAG_IS_DEDICATED 0x00000002
282#define DMA_CHANNEL_FLAG_NO_ISR 0x00000004
283#define DMA_CHANNEL_FLAG_LARGE_FIFO 0x00000008
284
285typedef struct {
286 uint32_t flags; /* bitmask of DMA_CHANNEL_FLAG_xxx constants */
287 DMA_Device_t devType; /* Device this channel is currently reserved for */
288 DMA_Device_t lastDevType; /* Device type that used this previously */
289 char name[20]; /* Name passed onto request_irq */
290
291#if (DMA_DEBUG_TRACK_RESERVATION)
292 const char *fileName; /* Place where channel reservation took place */
293 int lineNum; /* Place where channel reservation took place */
294#endif
295 dmacHw_HANDLE_t dmacHwHandle; /* low level channel handle. */
296
297} DMA_Channel_t;
298
299/****************************************************************************
300*
301* The DMA_Controller_t contains state information about each DMA controller.
302*
303* The freeChannelQ is stored in the controller data structure rather than
304* the channel data structure since several of the devices are accessible
305* from multiple controllers, and there is no way to know which controller
306* will become available first.
307*
308*****************************************************************************/
309
310typedef struct {
311 DMA_Channel_t channel[DMA_NUM_CHANNELS];
312
313} DMA_Controller_t;
314
315/****************************************************************************
316*
317* The DMA_Global_t contains all of the global state information used by
318* the DMA code.
319*
320* Callers which need to allocate a shared channel will be queued up
321* on the freeChannelQ until a channel becomes available.
322*
323*****************************************************************************/
324
325typedef struct {
326 struct semaphore lock; /* acquired when manipulating table entries */
327 wait_queue_head_t freeChannelQ;
328
329 DMA_Controller_t controller[DMA_NUM_CONTROLLERS];
330
331} DMA_Global_t;
332
333/* ---- Variable Externs ------------------------------------------------- */
334
335extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES];
336
337/* ---- Function Prototypes ---------------------------------------------- */
338
339#if defined(__KERNEL__)
340
341/****************************************************************************/
342/**
343* Initializes the DMA module.
344*
345* @return
346* 0 - Success
347* < 0 - Error
348*/
349/****************************************************************************/
350
351int dma_init(void);
352
353#if (DMA_DEBUG_TRACK_RESERVATION)
354DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName,
355 int lineNum);
356#define dma_request_channel(dev) dma_request_channel_dbg(dev, __FILE__, __LINE__)
357#else
358
359/****************************************************************************/
360/**
361* Reserves a channel for use with @a dev. If the device is setup to use
362* a shared channel, then this function will block until a free channel
363* becomes available.
364*
365* @return
366* >= 0 - A valid DMA Handle.
367* -EBUSY - Device is currently being used.
368* -ENODEV - Device handed in is invalid.
369*/
370/****************************************************************************/
371
372DMA_Handle_t dma_request_channel(DMA_Device_t dev /* Device to use with the allocated channel. */
373 );
374#endif
375
376/****************************************************************************/
377/**
378* Frees a previously allocated DMA Handle.
379*
380* @return
381* 0 - DMA Handle was released successfully.
382* -EINVAL - Invalid DMA handle
383*/
384/****************************************************************************/
385
386int dma_free_channel(DMA_Handle_t channel /* DMA handle. */
387 );
388
389/****************************************************************************/
390/**
391* Determines if a given device has been configured as using a shared
392* channel.
393*
394* @return boolean
395* 0 Device uses a dedicated channel
396* non-zero Device uses a shared channel
397*/
398/****************************************************************************/
399
400int dma_device_is_channel_shared(DMA_Device_t dev /* Device to check. */
401 );
402
403/****************************************************************************/
404/**
405* Allocates memory to hold a descriptor ring. The descriptor ring then
406* needs to be populated by making one or more calls to
407* dna_add_descriptors.
408*
409* The returned descriptor ring will be automatically initialized.
410*
411* @return
412* 0 Descriptor ring was allocated successfully
413* -ENOMEM Unable to allocate memory for the desired number of descriptors.
414*/
415/****************************************************************************/
416
417int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */
418 int numDescriptors /* Number of descriptors that need to be allocated. */
419 );
420
421/****************************************************************************/
422/**
423* Releases the memory which was previously allocated for a descriptor ring.
424*/
425/****************************************************************************/
426
427void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */
428 );
429
430/****************************************************************************/
431/**
432* Initializes a descriptor ring, so that descriptors can be added to it.
433* Once a descriptor ring has been allocated, it may be reinitialized for
434* use with additional/different regions of memory.
435*
436* Note that if 7 descriptors are allocated, it's perfectly acceptable to
437* initialize the ring with a smaller number of descriptors. The amount
438* of memory allocated for the descriptor ring will not be reduced, and
439* the descriptor ring may be reinitialized later
440*
441* @return
442* 0 Descriptor ring was initialized successfully
443* -ENOMEM The descriptor which was passed in has insufficient space
444* to hold the desired number of descriptors.
445*/
446/****************************************************************************/
447
448int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */
449 int numDescriptors /* Number of descriptors to initialize. */
450 );
451
452/****************************************************************************/
453/**
454* Determines the number of descriptors which would be required for a
455* transfer of the indicated memory region.
456*
457* This function also needs to know which DMA device this transfer will
458* be destined for, so that the appropriate DMA configuration can be retrieved.
459* DMA parameters such as transfer width, and whether this is a memory-to-memory
460* or memory-to-peripheral, etc can all affect the actual number of descriptors
461* required.
462*
463* @return
464* > 0 Returns the number of descriptors required for the indicated transfer
465* -EINVAL Invalid device type for this kind of transfer
466* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
467* -ENOMEM Memory exhausted
468*/
469/****************************************************************************/
470
471int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */
472 dma_addr_t srcData, /* Place to get data to write to device */
473 dma_addr_t dstData, /* Pointer to device data address */
474 size_t numBytes /* Number of bytes to transfer to the device */
475 );
476
477/****************************************************************************/
478/**
479* Adds a region of memory to the descriptor ring. Note that it may take
480* multiple descriptors for each region of memory. It is the callers
481* responsibility to allocate a sufficiently large descriptor ring.
482*
483* @return
484* 0 Descriptors were added successfully
485* -EINVAL Invalid device type for this kind of transfer
486* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
487* -ENOMEM Memory exhausted
488*/
489/****************************************************************************/
490
491int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */
492 DMA_Device_t device, /* DMA Device that descriptors are for */
493 dma_addr_t srcData, /* Place to get data (memory or device) */
494 dma_addr_t dstData, /* Place to put data (memory or device) */
495 size_t numBytes /* Number of bytes to transfer to the device */
496 );
497
498/****************************************************************************/
499/**
500* Sets the descriptor ring associated with a device.
501*
502* Once set, the descriptor ring will be associated with the device, even
503* across channel request/free calls. Passing in a NULL descriptor ring
504* will release any descriptor ring currently associated with the device.
505*
506* Note: If you call dma_transfer, or one of the other dma_alloc_ functions
507* the descriptor ring may be released and reallocated.
508*
509* Note: This function will release the descriptor memory for any current
510* descriptor ring associated with this device.
511*/
512/****************************************************************************/
513
514int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */
515 DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */
516 );
517
518/****************************************************************************/
519/**
520* Retrieves the descriptor ring associated with a device.
521*/
522/****************************************************************************/
523
524int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */
525 DMA_DescriptorRing_t *ring /* Place to store retrieved ring */
526 );
527
528/****************************************************************************/
529/**
530* Allocates buffers for the descriptors. This is normally done automatically
531* but needs to be done explicitly when initiating a dma from interrupt
532* context.
533*
534* @return
535* 0 Descriptors were allocated successfully
536* -EINVAL Invalid device type for this kind of transfer
537* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
538* -ENOMEM Memory exhausted
539*/
540/****************************************************************************/
541
542int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */
543 dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
544 dma_addr_t srcData, /* Place to get data to write to device */
545 dma_addr_t dstData, /* Pointer to device data address */
546 size_t numBytes /* Number of bytes to transfer to the device */
547 );
548
549/****************************************************************************/
550/**
551* Allocates and sets up descriptors for a double buffered circular buffer.
552*
553* This is primarily intended to be used for things like the ingress samples
554* from a microphone.
555*
556* @return
557* > 0 Number of descriptors actually allocated.
558* -EINVAL Invalid device type for this kind of transfer
559* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
560* -ENOMEM Memory exhausted
561*/
562/****************************************************************************/
563
564int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
565 dma_addr_t srcData, /* Physical address of source data */
566 dma_addr_t dstData1, /* Physical address of first destination buffer */
567 dma_addr_t dstData2, /* Physical address of second destination buffer */
568 size_t numBytes /* Number of bytes in each destination buffer */
569 );
570
571/****************************************************************************/
572/**
573* Initializes a DMA_MemMap_t data structure
574*/
575/****************************************************************************/
576
577int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
578 );
579
580/****************************************************************************/
581/**
582* Releases any memory currently being held by a memory mapping structure.
583*/
584/****************************************************************************/
585
586int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
587 );
588
589/****************************************************************************/
590/**
591* Looks at a memory address and categorizes it.
592*
593* @return One of the values from the DMA_MemType_t enumeration.
594*/
595/****************************************************************************/
596
597DMA_MemType_t dma_mem_type(void *addr);
598
599/****************************************************************************/
600/**
601* Sets the process (aka userTask) associated with a mem map. This is
602* required if user-mode segments will be added to the mapping.
603*/
604/****************************************************************************/
605
606static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
607 struct task_struct *task)
608{
609 memMap->userTask = task;
610}
611
612/****************************************************************************/
613/**
614* Looks at a memory address and determines if we support DMA'ing to/from
615* that type of memory.
616*
617* @return boolean -
618* return value != 0 means dma supported
619* return value == 0 means dma not supported
620*/
621/****************************************************************************/
622
623int dma_mem_supports_dma(void *addr);
624
625/****************************************************************************/
626/**
627* Initializes a memory map for use. Since this function acquires a
628* sempaphore within the memory map, it is VERY important that dma_unmap
629* be called when you're finished using the map.
630*/
631/****************************************************************************/
632
633int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
634 enum dma_data_direction dir /* Direction that the mapping will be going */
635 );
636
637/****************************************************************************/
638/**
639* Adds a segment of memory to a memory map.
640*
641* @return 0 on success, error code otherwise.
642*/
643/****************************************************************************/
644
645int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
646 void *mem, /* Virtual address that we want to get a map of */
647 size_t numBytes /* Number of bytes being mapped */
648 );
649
650/****************************************************************************/
651/**
652* Creates a descriptor ring from a memory mapping.
653*
654* @return 0 on sucess, error code otherwise.
655*/
656/****************************************************************************/
657
658int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
659 DMA_MemMap_t *memMap, /* Memory map that will be used */
660 dma_addr_t devPhysAddr /* Physical address of device */
661 );
662
663/****************************************************************************/
664/**
665* Maps in a memory region such that it can be used for performing a DMA.
666*
667* @return
668*/
669/****************************************************************************/
670
671int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
672 void *addr, /* Virtual address that we want to get a map of */
673 size_t count, /* Number of bytes being mapped */
674 enum dma_data_direction dir /* Direction that the mapping will be going */
675 );
676
677/****************************************************************************/
678/**
679* Maps in a memory region such that it can be used for performing a DMA.
680*
681* @return
682*/
683/****************************************************************************/
684
685int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
686 int dirtied /* non-zero if any of the pages were modified */
687 );
688
689/****************************************************************************/
690/**
691* Initiates a transfer when the descriptors have already been setup.
692*
693* This is a special case, and normally, the dma_transfer_xxx functions should
694* be used.
695*
696* @return
697* 0 Transfer was started successfully
698* -ENODEV Invalid handle
699*/
700/****************************************************************************/
701
702int dma_start_transfer(DMA_Handle_t handle);
703
704/****************************************************************************/
705/**
706* Stops a previously started DMA transfer.
707*
708* @return
709* 0 Transfer was stopped successfully
710* -ENODEV Invalid handle
711*/
712/****************************************************************************/
713
714int dma_stop_transfer(DMA_Handle_t handle);
715
716/****************************************************************************/
717/**
718* Waits for a DMA to complete by polling. This function is only intended
719* to be used for testing. Interrupts should be used for most DMA operations.
720*/
721/****************************************************************************/
722
723int dma_wait_transfer_done(DMA_Handle_t handle);
724
725/****************************************************************************/
726/**
727* Initiates a DMA transfer
728*
729* @return
730* 0 Transfer was started successfully
731* -EINVAL Invalid device type for this kind of transfer
732* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
733*/
734/****************************************************************************/
735
736int dma_transfer(DMA_Handle_t handle, /* DMA Handle */
737 dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
738 dma_addr_t srcData, /* Place to get data to write to device */
739 dma_addr_t dstData, /* Pointer to device data address */
740 size_t numBytes /* Number of bytes to transfer to the device */
741 );
742
743/****************************************************************************/
744/**
745* Initiates a transfer from memory to a device.
746*
747* @return
748* 0 Transfer was started successfully
749* -EINVAL Invalid device type for this kind of transfer
750* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
751*/
752/****************************************************************************/
753
754static inline int dma_transfer_to_device(DMA_Handle_t handle, /* DMA Handle */
755 dma_addr_t srcData, /* Place to get data to write to device (physical address) */
756 dma_addr_t dstData, /* Pointer to device data address (physical address) */
757 size_t numBytes /* Number of bytes to transfer to the device */
758 ) {
759 return dma_transfer(handle,
760 dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
761 srcData, dstData, numBytes);
762}
763
764/****************************************************************************/
765/**
766* Initiates a transfer from a device to memory.
767*
768* @return
769* 0 Transfer was started successfully
770* -EINVAL Invalid device type for this kind of transfer
771* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
772*/
773/****************************************************************************/
774
775static inline int dma_transfer_from_device(DMA_Handle_t handle, /* DMA Handle */
776 dma_addr_t srcData, /* Pointer to the device data address (physical address) */
777 dma_addr_t dstData, /* Place to store data retrieved from the device (physical address) */
778 size_t numBytes /* Number of bytes to retrieve from the device */
779 ) {
780 return dma_transfer(handle,
781 dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
782 srcData, dstData, numBytes);
783}
784
785/****************************************************************************/
786/**
787* Initiates a memory to memory transfer.
788*
789* @return
790* 0 Transfer was started successfully
791* -EINVAL Invalid device type for this kind of transfer
792* (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM)
793*/
794/****************************************************************************/
795
796static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle, /* DMA Handle */
797 dma_addr_t srcData, /* Place to transfer data from (physical address) */
798 dma_addr_t dstData, /* Place to transfer data to (physical address) */
799 size_t numBytes /* Number of bytes to transfer */
800 ) {
801 return dma_transfer(handle,
802 dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
803 srcData, dstData, numBytes);
804}
805
806/****************************************************************************/
807/**
808* Set the callback function which will be called when a transfer completes.
809* If a NULL callback function is set, then no callback will occur.
810*
811* @note @a devHandler will be called from IRQ context.
812*
813* @return
814* 0 - Success
815* -ENODEV - Device handed in is invalid.
816*/
817/****************************************************************************/
818
819int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */
820 DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */
821 void *userData /* Pointer which will be passed to devHandler. */
822 );
823
824#endif
825
826#endif /* ASM_ARM_ARCH_BCMRING_DMA_H */
diff --git a/arch/arm/mach-bcmring/include/mach/entry-macro.S b/arch/arm/mach-bcmring/include/mach/entry-macro.S
new file mode 100644
index 000000000000..7d393ca010ac
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/entry-macro.S
@@ -0,0 +1,86 @@
1/*****************************************************************************
2* Copyright 2006 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/*
16 *
17 * Low-level IRQ helper macros for BCMRing-based platforms
18 *
19 */
20#include <mach/irqs.h>
21#include <mach/hardware.h>
22#include <mach/csp/mm_io.h>
23
24 .macro disable_fiq
25 .endm
26
27 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
28 ldr \base, =(MM_IO_BASE_INTC0)
29 ldr \irqstat, [\base, #0] @ get status
30 ldr \irqnr, [\base, #0x10] @ mask with enable register
31 ands \irqstat, \irqstat, \irqnr
32 mov \irqnr, #IRQ_INTC0_START
33 cmp \irqstat, #0
34 bne 1001f
35
36 ldr \base, =(MM_IO_BASE_INTC1)
37 ldr \irqstat, [\base, #0] @ get status
38 ldr \irqnr, [\base, #0x10] @ mask with enable register
39 ands \irqstat, \irqstat, \irqnr
40 mov \irqnr, #IRQ_INTC1_START
41 cmp \irqstat, #0
42 bne 1001f
43
44 ldr \base, =(MM_IO_BASE_SINTC)
45 ldr \irqstat, [\base, #0] @ get status
46 ldr \irqnr, [\base, #0x10] @ mask with enable register
47 ands \irqstat, \irqstat, \irqnr
48 mov \irqnr, #0xffffffff @ code meaning no interrupt bits set
49 cmp \irqstat, #0
50 beq 1002f
51
52 mov \irqnr, #IRQ_SINTC_START @ something is set, so fixup return value
53
541001:
55 movs \tmp, \irqstat, lsl #16
56 movne \irqstat, \tmp
57 addeq \irqnr, \irqnr, #16
58
59 movs \tmp, \irqstat, lsl #8
60 movne \irqstat, \tmp
61 addeq \irqnr, \irqnr, #8
62
63 movs \tmp, \irqstat, lsl #4
64 movne \irqstat, \tmp
65 addeq \irqnr, \irqnr, #4
66
67 movs \tmp, \irqstat, lsl #2
68 movne \irqstat, \tmp
69 addeq \irqnr, \irqnr, #2
70
71 movs \tmp, \irqstat, lsl #1
72 addeq \irqnr, \irqnr, #1
73 orrs \base, \base, #1
74
751002: @ irqnr will be set to 0xffffffff if no irq bits are set
76 .endm
77
78 .macro get_irqnr_preamble, base, tmp
79 .endm
80
81 .macro arch_ret_to_user, tmp1, tmp2
82 .endm
83
84 .macro irq_prio_table
85 .endm
86
diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h
new file mode 100644
index 000000000000..447eb340c611
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/hardware.h
@@ -0,0 +1,60 @@
1/*
2 *
3 * This file contains the hardware definitions of the BCMRing.
4 *
5 * Copyright (C) 1999 ARM Limited.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef __ASM_ARCH_HARDWARE_H
22#define __ASM_ARCH_HARDWARE_H
23
24#include <asm/sizes.h>
25#include <mach/memory.h>
26#include <cfg_global.h>
27#include <mach/csp/mm_io.h>
28
29/* Hardware addresses of major areas.
30 * *_START is the physical address
31 * *_SIZE is the size of the region
32 * *_BASE is the virtual address
33 */
34#define RAM_START PHYS_OFFSET
35
36#define RAM_SIZE (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED)
37#define RAM_BASE PAGE_OFFSET
38
39#define pcibios_assign_all_busses() 1
40
41/* Macros to make managing spinlocks a bit more controlled in terms of naming. */
42/* See reg_gpio.h, reg_irq.h, arch.c, gpio.c for example usage. */
43#if defined(__KERNEL__)
44#define HW_DECLARE_SPINLOCK(name) DEFINE_SPINLOCK(bcmring_##name##_reg_lock);
45#define HW_EXTERN_SPINLOCK(name) extern spinlock_t bcmring_##name##_reg_lock;
46#define HW_IRQ_SAVE(name, val) spin_lock_irqsave(&bcmring_##name##_reg_lock, (val))
47#define HW_IRQ_RESTORE(name, val) spin_unlock_irqrestore(&bcmring_##name##_reg_lock, (val))
48#else
49#define HW_DECLARE_SPINLOCK(name)
50#define HW_EXTERN_SPINLOCK(name)
51#define HW_IRQ_SAVE(name, val) {(void)(name); (void)(val); }
52#define HW_IRQ_RESTORE(name, val) {(void)(name); (void)(val); }
53#endif
54
55#ifndef HW_IO_PHYS_TO_VIRT
56#define HW_IO_PHYS_TO_VIRT MM_IO_PHYS_TO_VIRT
57#endif
58#define HW_IO_VIRT_TO_PHYS MM_IO_VIRT_TO_PHYS
59
60#endif
diff --git a/arch/arm/mach-bcmring/include/mach/io.h b/arch/arm/mach-bcmring/include/mach/io.h
new file mode 100644
index 000000000000..4db0eff90357
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/io.h
@@ -0,0 +1,56 @@
1/*
2 *
3 * Copyright (C) 1999 ARM Limited
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#ifndef __ASM_ARM_ARCH_IO_H
20#define __ASM_ARM_ARCH_IO_H
21
22#include <mach/hardware.h>
23
24#define IO_SPACE_LIMIT 0xffffffff
25
26#define __io(a) ((void __iomem *)HW_IO_PHYS_TO_VIRT(a))
27
28/* Do not enable mem_pci for a big endian arm architecture or unexpected byteswaps will */
29/* happen in readw/writew etc. */
30
31#define readb(c) __raw_readb(c)
32#define readw(c) __raw_readw(c)
33#define readl(c) __raw_readl(c)
34#define readb_relaxed(addr) readb(addr)
35#define readw_relaxed(addr) readw(addr)
36#define readl_relaxed(addr) readl(addr)
37
38#define readsb(p, d, l) __raw_readsb(p, d, l)
39#define readsw(p, d, l) __raw_readsw(p, d, l)
40#define readsl(p, d, l) __raw_readsl(p, d, l)
41
42#define writeb(v, c) __raw_writeb(v, c)
43#define writew(v, c) __raw_writew(v, c)
44#define writel(v, c) __raw_writel(v, c)
45
46#define writesb(p, d, l) __raw_writesb(p, d, l)
47#define writesw(p, d, l) __raw_writesw(p, d, l)
48#define writesl(p, d, l) __raw_writesl(p, d, l)
49
50#define memset_io(c, v, l) _memset_io((c), (v), (l))
51#define memcpy_fromio(a, c, l) _memcpy_fromio((a), (c), (l))
52#define memcpy_toio(c, a, l) _memcpy_toio((c), (a), (l))
53
54#define eth_io_copy_and_sum(s, c, l, b) eth_copy_and_sum((s), (c), (l), (b))
55
56#endif
diff --git a/arch/arm/mach-bcmring/include/mach/irqs.h b/arch/arm/mach-bcmring/include/mach/irqs.h
new file mode 100644
index 000000000000..b279b825d4a7
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/irqs.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (C) 2007 Broadcom
3 * Copyright (C) 1999 ARM Limited
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#if !defined(ARCH_BCMRING_IRQS_H)
21#define ARCH_BCMRING_IRQS_H
22
23/* INTC0 - interrupt controller 0 */
24#define IRQ_INTC0_START 0
25#define IRQ_DMA0C0 0 /* DMA0 channel 0 interrupt */
26#define IRQ_DMA0C1 1 /* DMA0 channel 1 interrupt */
27#define IRQ_DMA0C2 2 /* DMA0 channel 2 interrupt */
28#define IRQ_DMA0C3 3 /* DMA0 channel 3 interrupt */
29#define IRQ_DMA0C4 4 /* DMA0 channel 4 interrupt */
30#define IRQ_DMA0C5 5 /* DMA0 channel 5 interrupt */
31#define IRQ_DMA0C6 6 /* DMA0 channel 6 interrupt */
32#define IRQ_DMA0C7 7 /* DMA0 channel 7 interrupt */
33#define IRQ_DMA1C0 8 /* DMA1 channel 0 interrupt */
34#define IRQ_DMA1C1 9 /* DMA1 channel 1 interrupt */
35#define IRQ_DMA1C2 10 /* DMA1 channel 2 interrupt */
36#define IRQ_DMA1C3 11 /* DMA1 channel 3 interrupt */
37#define IRQ_DMA1C4 12 /* DMA1 channel 4 interrupt */
38#define IRQ_DMA1C5 13 /* DMA1 channel 5 interrupt */
39#define IRQ_DMA1C6 14 /* DMA1 channel 6 interrupt */
40#define IRQ_DMA1C7 15 /* DMA1 channel 7 interrupt */
41#define IRQ_VPM 16 /* Voice process module interrupt */
42#define IRQ_USBHD2 17 /* USB host2/device2 interrupt */
43#define IRQ_USBH1 18 /* USB1 host interrupt */
44#define IRQ_USBD 19 /* USB device interrupt */
45#define IRQ_SDIOH0 20 /* SDIO0 host interrupt */
46#define IRQ_SDIOH1 21 /* SDIO1 host interrupt */
47#define IRQ_TIMER0 22 /* Timer0 interrupt */
48#define IRQ_TIMER1 23 /* Timer1 interrupt */
49#define IRQ_TIMER2 24 /* Timer2 interrupt */
50#define IRQ_TIMER3 25 /* Timer3 interrupt */
51#define IRQ_SPIH 26 /* SPI host interrupt */
52#define IRQ_ESW 27 /* Ethernet switch interrupt */
53#define IRQ_APM 28 /* Audio process module interrupt */
54#define IRQ_GE 29 /* Graphic engine interrupt */
55#define IRQ_CLCD 30 /* LCD Controller interrupt */
56#define IRQ_PIF 31 /* Peripheral interface interrupt */
57#define IRQ_INTC0_END 31
58
59/* INTC1 - interrupt controller 1 */
60#define IRQ_INTC1_START 32
61#define IRQ_GPIO0 32 /* 0 GPIO bit 31//0 combined interrupt */
62#define IRQ_GPIO1 33 /* 1 GPIO bit 64//32 combined interrupt */
63#define IRQ_I2S0 34 /* 2 I2S0 interrupt */
64#define IRQ_I2S1 35 /* 3 I2S1 interrupt */
65#define IRQ_I2CH 36 /* 4 I2C host interrupt */
66#define IRQ_I2CS 37 /* 5 I2C slave interrupt */
67#define IRQ_SPIS 38 /* 6 SPI slave interrupt */
68#define IRQ_GPHY 39 /* 7 Gigabit Phy interrupt */
69#define IRQ_FLASHC 40 /* 8 Flash controller interrupt */
70#define IRQ_COMMTX 41 /* 9 ARM DDC transmit interrupt */
71#define IRQ_COMMRX 42 /* 10 ARM DDC receive interrupt */
72#define IRQ_PMUIRQ 43 /* 11 ARM performance monitor interrupt */
73#define IRQ_UARTB 44 /* 12 UARTB */
74#define IRQ_WATCHDOG 45 /* 13 Watchdog timer interrupt */
75#define IRQ_UARTA 46 /* 14 UARTA */
76#define IRQ_TSC 47 /* 15 Touch screen controller interrupt */
77#define IRQ_KEYC 48 /* 16 Key pad controller interrupt */
78#define IRQ_DMPU 49 /* 17 DDR2 memory partition interrupt */
79#define IRQ_VMPU 50 /* 18 VRAM memory partition interrupt */
80#define IRQ_FMPU 51 /* 19 Flash memory parition unit interrupt */
81#define IRQ_RNG 52 /* 20 Random number generator interrupt */
82#define IRQ_RTC0 53 /* 21 Real time clock periodic interrupt */
83#define IRQ_RTC1 54 /* 22 Real time clock one-shot interrupt */
84#define IRQ_SPUM 55 /* 23 Secure process module interrupt */
85#define IRQ_VDEC 56 /* 24 Hantro video decoder interrupt */
86#define IRQ_RTC2 57 /* 25 Real time clock tamper interrupt */
87#define IRQ_DDRP 58 /* 26 DDR Panic interrupt */
88#define IRQ_INTC1_END 58
89
90/* SINTC secure int controller */
91#define IRQ_SINTC_START 59
92#define IRQ_SEC_WATCHDOG 59 /* 0 Watchdog timer interrupt */
93#define IRQ_SEC_UARTA 60 /* 1 UARTA interrupt */
94#define IRQ_SEC_TSC 61 /* 2 Touch screen controller interrupt */
95#define IRQ_SEC_KEYC 62 /* 3 Key pad controller interrupt */
96#define IRQ_SEC_DMPU 63 /* 4 DDR2 memory partition interrupt */
97#define IRQ_SEC_VMPU 64 /* 5 VRAM memory partition interrupt */
98#define IRQ_SEC_FMPU 65 /* 6 Flash memory parition unit interrupt */
99#define IRQ_SEC_RNG 66 /* 7 Random number generator interrupt */
100#define IRQ_SEC_RTC0 67 /* 8 Real time clock periodic interrupt */
101#define IRQ_SEC_RTC1 68 /* 9 Real time clock one-shot interrupt */
102#define IRQ_SEC_SPUM 69 /* 10 Secure process module interrupt */
103#define IRQ_SEC_TIMER0 70 /* 11 Secure timer0 interrupt */
104#define IRQ_SEC_TIMER1 71 /* 12 Secure timer1 interrupt */
105#define IRQ_SEC_TIMER2 72 /* 13 Secure timer2 interrupt */
106#define IRQ_SEC_TIMER3 73 /* 14 Secure timer3 interrupt */
107#define IRQ_SEC_RTC2 74 /* 15 Real time clock tamper interrupt */
108
109#define IRQ_SINTC_END 74
110
111/* Note: there are 3 INTC registers of 32 bits each. So internal IRQs could go from 0-95 */
112/* Since IRQs are typically viewed in decimal, we start the gpio based IRQs off at 100 */
113/* to make the mapping easy for humans to decipher. */
114
115#define IRQ_GPIO_0 100
116
117#define NUM_INTERNAL_IRQS (IRQ_SINTC_END+1)
118
119/* I couldn't get the gpioHw_reg.h file to be included cleanly, so I hardcoded it */
120/* define NUM_GPIO_IRQS GPIOHW_TOTAL_NUM_PINS */
121#define NUM_GPIO_IRQS 62
122
123#define NR_IRQS (IRQ_GPIO_0 + NUM_GPIO_IRQS)
124
125#define IRQ_UNKNOWN -1
126
127/* Tune these bits to preclude noisy or unsupported interrupt sources as required. */
128#define IRQ_INTC0_VALID_MASK 0xffffffff
129#define IRQ_INTC1_VALID_MASK 0x07ffffff
130#define IRQ_SINTC_VALID_MASK 0x0000ffff
131
132#endif /* ARCH_BCMRING_IRQS_H */
diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h
new file mode 100644
index 000000000000..114f942bb4f3
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/memory.h
@@ -0,0 +1,33 @@
1/*****************************************************************************
2* Copyright 2005 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef __ASM_ARCH_MEMORY_H
16#define __ASM_ARCH_MEMORY_H
17
18#include <cfg_global.h>
19
20/*
21 * Physical vs virtual RAM address space conversion. These are
22 * private definitions which should NOT be used outside memory.h
23 * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
24 */
25
26#define PHYS_OFFSET CFG_GLOBAL_RAM_BASE
27
28/*
29 * Maximum DMA memory allowed is 14M
30 */
31#define CONSISTENT_DMA_SIZE (SZ_16M - SZ_2M)
32
33#endif
diff --git a/arch/arm/mach-bcmring/include/mach/memory_settings.h b/arch/arm/mach-bcmring/include/mach/memory_settings.h
new file mode 100644
index 000000000000..ce5cd16f2ac4
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/memory_settings.h
@@ -0,0 +1,67 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#ifndef MEMORY_SETTINGS_H
16#define MEMORY_SETTINGS_H
17
18/* ---- Include Files ---------------------------------------- */
19/* ---- Constants and Types ---------------------------------- */
20
21/* Memory devices */
22/* NAND Flash timing for 166 MHz setting */
23#define HW_CFG_NAND_tBTA (5 << 16) /* Bus turnaround cycle (n) 0-7 (30 ns) */
24#define HW_CFG_NAND_tWP (4 << 11) /* Write pulse width cycle (n+1) 0-31 (25 ns) */
25#define HW_CFG_NAND_tWR (1 << 9) /* Write recovery cycle (n+1) 0-3 (10 ns) */
26#define HW_CFG_NAND_tAS (0 << 7) /* Write address setup cycle (n+1) 0-3 ( 0 ns) */
27#define HW_CFG_NAND_tOE (3 << 5) /* Output enable delay cycle (n) 0-3 (15 ns) */
28#define HW_CFG_NAND_tRC (7 << 0) /* Read access cycle (n+2) 0-31 (50 ns) */
29
30#define HW_CFG_NAND_TCR (HW_CFG_NAND_tBTA \
31 | HW_CFG_NAND_tWP \
32 | HW_CFG_NAND_tWR \
33 | HW_CFG_NAND_tAS \
34 | HW_CFG_NAND_tOE \
35 | HW_CFG_NAND_tRC)
36
37/* NOR Flash timing for 166 MHz setting */
38#define HW_CFG_NOR_TPRC_TWLC (0 << 19) /* Page read access cycle / Burst write latency (n+2 / n+1) (max 25ns) */
39#define HW_CFG_NOR_TBTA (0 << 16) /* Bus turnaround cycle (n) (DNA) */
40#define HW_CFG_NOR_TWP (6 << 11) /* Write pulse width cycle (n+1) (35ns) */
41#define HW_CFG_NOR_TWR (0 << 9) /* Write recovery cycle (n+1) (0ns) */
42#define HW_CFG_NOR_TAS (0 << 7) /* Write address setup cycle (n+1) (0ns) */
43#define HW_CFG_NOR_TOE (0 << 5) /* Output enable delay cycle (n) (max 25ns) */
44#define HW_CFG_NOR_TRC_TLC (0x10 << 0) /* Read access cycle / Burst read latency (n+2 / n+1) (100ns) */
45
46#define HW_CFG_FLASH0_TCR (HW_CFG_NOR_TPRC_TWLC \
47 | HW_CFG_NOR_TBTA \
48 | HW_CFG_NOR_TWP \
49 | HW_CFG_NOR_TWR \
50 | HW_CFG_NOR_TAS \
51 | HW_CFG_NOR_TOE \
52 | HW_CFG_NOR_TRC_TLC)
53
54#define HW_CFG_FLASH1_TCR HW_CFG_FLASH0_TCR
55#define HW_CFG_FLASH2_TCR HW_CFG_FLASH0_TCR
56
57/* SDRAM Settings */
58/* #define HW_CFG_SDRAM_CAS_LATENCY 5 Default 5, Values [3..6] */
59/* #define HW_CFG_SDRAM_CHIP_SELECT_CNT 1 Default 1, Vaules [1..2] */
60/* #define HW_CFG_SDRAM_SPEED_GRADE 667 Default 667, Values [400,533,667,800] */
61/* #define HW_CFG_SDRAM_WIDTH_BITS 16 Default 16, Vaules [8,16] */
62#define HW_CFG_SDRAM_SIZE_BYTES 0x10000000 /* Total memory, not per device size */
63
64/* ---- Variable Externs ------------------------------------- */
65/* ---- Function Prototypes ---------------------------------- */
66
67#endif /* MEMORY_SETTINGS_H */
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h
new file mode 100644
index 000000000000..cdbf93c694a6
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/system.h
@@ -0,0 +1,54 @@
1/*
2 *
3 * Copyright (C) 1999 ARM Limited
4 * Copyright (C) 2000 Deep Blue Solutions Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARCH_SYSTEM_H
21#define __ASM_ARCH_SYSTEM_H
22
23#include <mach/csp/chipcHw_inline.h>
24
25extern int bcmring_arch_warm_reboot;
26
27static inline void arch_idle(void)
28{
29 cpu_do_idle();
30}
31
32static inline void arch_reset(char mode, char *cmd)
33{
34 printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot);
35
36 if (mode == 'h') {
37 /* Reboot configured in proc entry */
38 if (bcmring_arch_warm_reboot) {
39 printk("warm reset\n");
40 /* Issue Warm reset (do not reset ethernet switch, keep alive) */
41 chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_WARM);
42 } else {
43 /* Force reset of everything */
44 printk("force reset\n");
45 chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
46 }
47 } else {
48 /* Force reset of everything */
49 printk("force reset\n");
50 chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
51 }
52}
53
54#endif
diff --git a/arch/arm/mach-bcmring/include/mach/timer.h b/arch/arm/mach-bcmring/include/mach/timer.h
new file mode 100644
index 000000000000..5a94bbb032b6
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/timer.h
@@ -0,0 +1,77 @@
1/*****************************************************************************
2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15/*
16*
17*****************************************************************************
18*
19* timer.h
20*
21* PURPOSE:
22*
23*
24*
25* NOTES:
26*
27*****************************************************************************/
28
29#if !defined(BCM_LINUX_TIMER_H)
30#define BCM_LINUX_TIMER_H
31
32#if defined(__KERNEL__)
33
34/* ---- Include Files ---------------------------------------------------- */
35/* ---- Constants and Types ---------------------------------------------- */
36
37typedef unsigned int timer_tick_count_t;
38typedef unsigned int timer_tick_rate_t;
39typedef unsigned int timer_msec_t;
40
41/* ---- Variable Externs ------------------------------------------------- */
42/* ---- Function Prototypes ---------------------------------------------- */
43
44/****************************************************************************
45*
46* timer_get_tick_count
47*
48*
49***************************************************************************/
50timer_tick_count_t timer_get_tick_count(void);
51
52/****************************************************************************
53*
54* timer_get_tick_rate
55*
56*
57***************************************************************************/
58timer_tick_rate_t timer_get_tick_rate(void);
59
60/****************************************************************************
61*
62* timer_get_msec
63*
64*
65***************************************************************************/
66timer_msec_t timer_get_msec(void);
67
68/****************************************************************************
69*
70* timer_ticks_to_msec
71*
72*
73***************************************************************************/
74timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks);
75
76#endif /* __KERNEL__ */
77#endif /* BCM_LINUX_TIMER_H */
diff --git a/arch/arm/mach-bcmring/include/mach/timex.h b/arch/arm/mach-bcmring/include/mach/timex.h
new file mode 100644
index 000000000000..40d033ec5892
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/timex.h
@@ -0,0 +1,25 @@
1/*
2 *
3 * Integrator architecture timex specifications
4 *
5 * Copyright (C) 1999 ARM Limited
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/*
23 * Specifies the number of ticks per second
24 */
25#define CLOCK_TICK_RATE 100000 /* REG_SMT_TICKS_PER_SEC */
diff --git a/arch/arm/mach-bcmring/include/mach/uncompress.h b/arch/arm/mach-bcmring/include/mach/uncompress.h
new file mode 100644
index 000000000000..9c9821b77977
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/uncompress.h
@@ -0,0 +1,43 @@
1/*****************************************************************************
2* Copyright 2005 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14#include <mach/csp/mm_addr.h>
15
16#define BCMRING_UART_0_DR (*(volatile unsigned int *)MM_ADDR_IO_UARTA)
17#define BCMRING_UART_0_FR (*(volatile unsigned int *)(MM_ADDR_IO_UARTA + 0x18))
18/*
19 * This does not append a newline
20 */
21static inline void putc(int c)
22{
23 /* Send out UARTA */
24 while (BCMRING_UART_0_FR & (1 << 5))
25 ;
26
27 BCMRING_UART_0_DR = c;
28}
29
30
31static inline void flush(void)
32{
33 /* Wait for the tx fifo to be empty */
34 while ((BCMRING_UART_0_FR & (1 << 7)) == 0)
35 ;
36
37 /* Wait for the final character to be sent on the txd line */
38 while (BCMRING_UART_0_FR & (1 << 3))
39 ;
40}
41
42#define arch_decomp_setup()
43#define arch_decomp_wdog()
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h
new file mode 100644
index 000000000000..35e2ead8395c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h
@@ -0,0 +1,25 @@
1/*
2 *
3 * Copyright (C) 2000 Russell King.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * Move VMALLOC_END to 0xf0000000 so that the vm space can range from
22 * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
23 * larger physical memory designs better.
24 */
25#define VMALLOC_END (PAGE_OFFSET + 0x30000000)
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
new file mode 100644
index 000000000000..dc1c4939b0ce
--- /dev/null
+++ b/arch/arm/mach-bcmring/irq.c
@@ -0,0 +1,127 @@
1/*
2 *
3 * Copyright (C) 1999 ARM Limited
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <linux/init.h>
20#include <linux/stddef.h>
21#include <linux/list.h>
22#include <linux/timer.h>
23#include <linux/version.h>
24#include <linux/io.h>
25
26#include <mach/hardware.h>
27#include <asm/irq.h>
28
29#include <asm/mach/irq.h>
30#include <mach/csp/intcHw_reg.h>
31#include <mach/csp/mm_io.h>
32
33static void bcmring_mask_irq0(unsigned int irq)
34{
35 writel(1 << (irq - IRQ_INTC0_START),
36 MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR);
37}
38
39static void bcmring_unmask_irq0(unsigned int irq)
40{
41 writel(1 << (irq - IRQ_INTC0_START),
42 MM_IO_BASE_INTC0 + INTCHW_INTENABLE);
43}
44
45static void bcmring_mask_irq1(unsigned int irq)
46{
47 writel(1 << (irq - IRQ_INTC1_START),
48 MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR);
49}
50
51static void bcmring_unmask_irq1(unsigned int irq)
52{
53 writel(1 << (irq - IRQ_INTC1_START),
54 MM_IO_BASE_INTC1 + INTCHW_INTENABLE);
55}
56
57static void bcmring_mask_irq2(unsigned int irq)
58{
59 writel(1 << (irq - IRQ_SINTC_START),
60 MM_IO_BASE_SINTC + INTCHW_INTENCLEAR);
61}
62
63static void bcmring_unmask_irq2(unsigned int irq)
64{
65 writel(1 << (irq - IRQ_SINTC_START),
66 MM_IO_BASE_SINTC + INTCHW_INTENABLE);
67}
68
69static struct irq_chip bcmring_irq0_chip = {
70 .typename = "ARM-INTC0",
71 .ack = bcmring_mask_irq0,
72 .mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */
73 .unmask = bcmring_unmask_irq0, /* unmaks an interrupt */
74};
75
76static struct irq_chip bcmring_irq1_chip = {
77 .typename = "ARM-INTC1",
78 .ack = bcmring_mask_irq1,
79 .mask = bcmring_mask_irq1,
80 .unmask = bcmring_unmask_irq1,
81};
82
83static struct irq_chip bcmring_irq2_chip = {
84 .typename = "ARM-SINTC",
85 .ack = bcmring_mask_irq2,
86 .mask = bcmring_mask_irq2,
87 .unmask = bcmring_unmask_irq2,
88};
89
90static void vic_init(void __iomem *base, struct irq_chip *chip,
91 unsigned int irq_start, unsigned int vic_sources)
92{
93 unsigned int i;
94 for (i = 0; i < 32; i++) {
95 unsigned int irq = irq_start + i;
96 set_irq_chip(irq, chip);
97 set_irq_chip_data(irq, base);
98
99 if (vic_sources & (1 << i)) {
100 set_irq_handler(irq, handle_level_irq);
101 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
102 }
103 }
104 writel(0, base + INTCHW_INTSELECT);
105 writel(0, base + INTCHW_INTENABLE);
106 writel(~0, base + INTCHW_INTENCLEAR);
107 writel(0, base + INTCHW_IRQSTATUS);
108 writel(~0, base + INTCHW_SOFTINTCLEAR);
109}
110
111void __init bcmring_init_irq(void)
112{
113 vic_init((void __iomem *)MM_IO_BASE_INTC0, &bcmring_irq0_chip,
114 IRQ_INTC0_START, IRQ_INTC0_VALID_MASK);
115 vic_init((void __iomem *)MM_IO_BASE_INTC1, &bcmring_irq1_chip,
116 IRQ_INTC1_START, IRQ_INTC1_VALID_MASK);
117 vic_init((void __iomem *)MM_IO_BASE_SINTC, &bcmring_irq2_chip,
118 IRQ_SINTC_START, IRQ_SINTC_VALID_MASK);
119
120 /* special cases */
121 if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) {
122 set_irq_handler(IRQ_GPIO0, handle_simple_irq);
123 }
124 if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) {
125 set_irq_handler(IRQ_GPIO1, handle_simple_irq);
126 }
127}
diff --git a/arch/arm/mach-bcmring/mm.c b/arch/arm/mach-bcmring/mm.c
new file mode 100644
index 000000000000..0f1c37e4523a
--- /dev/null
+++ b/arch/arm/mach-bcmring/mm.c
@@ -0,0 +1,56 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#include <linux/platform_device.h>
16#include <asm/mach/map.h>
17
18#include <mach/hardware.h>
19#include <mach/csp/mm_io.h>
20
21#define IO_DESC(va, sz) { .virtual = va, \
22 .pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \
23 .length = sz, \
24 .type = MT_DEVICE }
25
26#define MEM_DESC(va, sz) { .virtual = va, \
27 .pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \
28 .length = sz, \
29 .type = MT_MEMORY }
30
31static struct map_desc bcmring_io_desc[] __initdata = {
32 IO_DESC(MM_IO_BASE_NAND, SZ_64K), /* phys:0x28000000-0x28000FFF virt:0xE8000000-0xE8000FFF size:0x00010000 */
33 IO_DESC(MM_IO_BASE_UMI, SZ_64K), /* phys:0x2C000000-0x2C000FFF virt:0xEC000000-0xEC000FFF size:0x00010000 */
34
35 IO_DESC(MM_IO_BASE_BROM, SZ_64K), /* phys:0x30000000-0x3000FFFF virt:0xF3000000-0xF300FFFF size:0x00010000 */
36 MEM_DESC(MM_IO_BASE_ARAM, SZ_1M), /* phys:0x31000000-0x31FFFFFF virt:0xF3100000-0xF31FFFFF size:0x01000000 */
37 IO_DESC(MM_IO_BASE_DMA0, SZ_1M), /* phys:0x32000000-0x32FFFFFF virt:0xF3200000-0xF32FFFFF size:0x01000000 */
38 IO_DESC(MM_IO_BASE_DMA1, SZ_1M), /* phys:0x33000000-0x33FFFFFF virt:0xF3300000-0xF33FFFFF size:0x01000000 */
39 IO_DESC(MM_IO_BASE_ESW, SZ_1M), /* phys:0x34000000-0x34FFFFFF virt:0xF3400000-0xF34FFFFF size:0x01000000 */
40 IO_DESC(MM_IO_BASE_CLCD, SZ_1M), /* phys:0x35000000-0x35FFFFFF virt:0xF3500000-0xF35FFFFF size:0x01000000 */
41 IO_DESC(MM_IO_BASE_APM, SZ_1M), /* phys:0x36000000-0x36FFFFFF virt:0xF3600000-0xF36FFFFF size:0x01000000 */
42 IO_DESC(MM_IO_BASE_SPUM, SZ_1M), /* phys:0x37000000-0x37FFFFFF virt:0xF3700000-0xF37FFFFF size:0x01000000 */
43 IO_DESC(MM_IO_BASE_VPM_PROG, SZ_1M), /* phys:0x38000000-0x38FFFFFF virt:0xF3800000-0xF38FFFFF size:0x01000000 */
44 IO_DESC(MM_IO_BASE_VPM_DATA, SZ_1M), /* phys:0x3A000000-0x3AFFFFFF virt:0xF3A00000-0xF3AFFFFF size:0x01000000 */
45
46 IO_DESC(MM_IO_BASE_VRAM, SZ_64K), /* phys:0x40000000-0x4000FFFF virt:0xF4000000-0xF400FFFF size:0x00010000 */
47 IO_DESC(MM_IO_BASE_CHIPC, SZ_16M), /* phys:0x80000000-0x80FFFFFF virt:0xF8000000-0xF8FFFFFF size:0x01000000 */
48 IO_DESC(MM_IO_BASE_VPM_EXTMEM_RSVD,
49 SZ_16M), /* phys:0x0F000000-0x0FFFFFFF virt:0xF0000000-0xF0FFFFFF size:0x01000000 */
50};
51
52void __init bcmring_map_io(void)
53{
54
55 iotable_init(bcmring_io_desc, ARRAY_SIZE(bcmring_io_desc));
56}
diff --git a/arch/arm/mach-bcmring/timer.c b/arch/arm/mach-bcmring/timer.c
new file mode 100644
index 000000000000..2d415d2a8e68
--- /dev/null
+++ b/arch/arm/mach-bcmring/timer.c
@@ -0,0 +1,62 @@
1/*****************************************************************************
2* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
3*
4* Unless you and Broadcom execute a separate written software license
5* agreement governing use of this software, this software is licensed to you
6* under the terms of the GNU General Public License version 2, available at
7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8*
9* Notwithstanding the above, under no circumstances may you combine this
10* software in any way with any other Broadcom software provided under a
11* license other than the GPL, without Broadcom's express prior written
12* consent.
13*****************************************************************************/
14
15#include <linux/version.h>
16#include <linux/types.h>
17#include <linux/module.h>
18#include <csp/tmrHw.h>
19
20#include <mach/timer.h>
21/* The core.c file initializes timers 1 and 3 as a linux clocksource. */
22/* The real time clock should probably be the real linux clocksource. */
23/* In the meantime, this file should agree with core.c as to the */
24/* profiling timer. If the clocksource is moved to rtc later, then */
25/* we can init the profiling timer here instead. */
26
27/* Timer 1 provides 25MHz resolution syncrhonized to scheduling and APM timing */
28/* Timer 3 provides bus freqeuncy sychronized to ACLK, but spread spectrum will */
29/* affect synchronization with scheduling and APM timing. */
30
31#define PROF_TIMER 1
32
33timer_tick_rate_t timer_get_tick_rate(void)
34{
35 return tmrHw_getCountRate(PROF_TIMER);
36}
37
38timer_tick_count_t timer_get_tick_count(void)
39{
40 return tmrHw_GetCurrentCount(PROF_TIMER); /* change downcounter to upcounter */
41}
42
43timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks)
44{
45 static int tickRateMsec;
46
47 if (tickRateMsec == 0) {
48 tickRateMsec = timer_get_tick_rate() / 1000;
49 }
50
51 return ticks / tickRateMsec;
52}
53
54timer_msec_t timer_get_msec(void)
55{
56 return timer_ticks_to_msec(timer_get_tick_count());
57}
58
59EXPORT_SYMBOL(timer_get_tick_count);
60EXPORT_SYMBOL(timer_ticks_to_msec);
61EXPORT_SYMBOL(timer_get_tick_rate);
62EXPORT_SYMBOL(timer_get_msec);
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 3fbd9b0fbe24..caf6d5154aec 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -12,18 +12,15 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/mm.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/mtd/physmap.h>
20#include <linux/platform_device.h> 15#include <linux/platform_device.h>
21#include <linux/io.h> 16#include <linux/mtd/physmap.h>
22#include <linux/i2c.h> 17
23#include <mach/hardware.h> 18#include <mach/hardware.h>
19
24#include <asm/mach-types.h> 20#include <asm/mach-types.h>
25#include <asm/mach/arch.h> 21#include <asm/mach/arch.h>
26 22
23
27static struct physmap_flash_data adssphere_flash_data = { 24static struct physmap_flash_data adssphere_flash_data = {
28 .width = 4, 25 .width = 4,
29}; 26};
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 6c4c1633ed12..3dd0e2a23095 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -22,48 +22,39 @@
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23 23
24 24
25/*
26 * The EP93xx has two external crystal oscillators. To generate the
27 * required high-frequency clocks, the processor uses two phase-locked-
28 * loops (PLLs) to multiply the incoming external clock signal to much
29 * higher frequencies that are then divided down by programmable dividers
30 * to produce the needed clocks. The PLLs operate independently of one
31 * another.
32 */
33#define EP93XX_EXT_CLK_RATE 14745600
34#define EP93XX_EXT_RTC_RATE 32768
35
36
37struct clk { 25struct clk {
38 unsigned long rate; 26 unsigned long rate;
39 int users; 27 int users;
40 int sw_locked; 28 int sw_locked;
41 u32 enable_reg; 29 void __iomem *enable_reg;
42 u32 enable_mask; 30 u32 enable_mask;
43 31
44 unsigned long (*get_rate)(struct clk *clk); 32 unsigned long (*get_rate)(struct clk *clk);
33 int (*set_rate)(struct clk *clk, unsigned long rate);
45}; 34};
46 35
47 36
48static unsigned long get_uart_rate(struct clk *clk); 37static unsigned long get_uart_rate(struct clk *clk);
49 38
39static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
40
50 41
51static struct clk clk_uart1 = { 42static struct clk clk_uart1 = {
52 .sw_locked = 1, 43 .sw_locked = 1,
53 .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, 44 .enable_reg = EP93XX_SYSCON_DEVCFG,
54 .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, 45 .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
55 .get_rate = get_uart_rate, 46 .get_rate = get_uart_rate,
56}; 47};
57static struct clk clk_uart2 = { 48static struct clk clk_uart2 = {
58 .sw_locked = 1, 49 .sw_locked = 1,
59 .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, 50 .enable_reg = EP93XX_SYSCON_DEVCFG,
60 .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, 51 .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
61 .get_rate = get_uart_rate, 52 .get_rate = get_uart_rate,
62}; 53};
63static struct clk clk_uart3 = { 54static struct clk clk_uart3 = {
64 .sw_locked = 1, 55 .sw_locked = 1,
65 .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, 56 .enable_reg = EP93XX_SYSCON_DEVCFG,
66 .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, 57 .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
67 .get_rate = get_uart_rate, 58 .get_rate = get_uart_rate,
68}; 59};
69static struct clk clk_pll1; 60static struct clk clk_pll1;
@@ -75,6 +66,15 @@ static struct clk clk_usb_host = {
75 .enable_reg = EP93XX_SYSCON_PWRCNT, 66 .enable_reg = EP93XX_SYSCON_PWRCNT,
76 .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, 67 .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN,
77}; 68};
69static struct clk clk_keypad = {
70 .sw_locked = 1,
71 .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
72 .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
73 .set_rate = set_keytchclk_rate,
74};
75static struct clk clk_pwm = {
76 .rate = EP93XX_EXT_CLK_RATE,
77};
78 78
79/* DMA Clocks */ 79/* DMA Clocks */
80static struct clk clk_m2p0 = { 80static struct clk clk_m2p0 = {
@@ -130,27 +130,29 @@ static struct clk clk_m2m1 = {
130 { .dev_id = dev, .con_id = con, .clk = ck } 130 { .dev_id = dev, .con_id = con, .clk = ck }
131 131
132static struct clk_lookup clocks[] = { 132static struct clk_lookup clocks[] = {
133 INIT_CK("apb:uart1", NULL, &clk_uart1), 133 INIT_CK("apb:uart1", NULL, &clk_uart1),
134 INIT_CK("apb:uart2", NULL, &clk_uart2), 134 INIT_CK("apb:uart2", NULL, &clk_uart2),
135 INIT_CK("apb:uart3", NULL, &clk_uart3), 135 INIT_CK("apb:uart3", NULL, &clk_uart3),
136 INIT_CK(NULL, "pll1", &clk_pll1), 136 INIT_CK(NULL, "pll1", &clk_pll1),
137 INIT_CK(NULL, "fclk", &clk_f), 137 INIT_CK(NULL, "fclk", &clk_f),
138 INIT_CK(NULL, "hclk", &clk_h), 138 INIT_CK(NULL, "hclk", &clk_h),
139 INIT_CK(NULL, "pclk", &clk_p), 139 INIT_CK(NULL, "pclk", &clk_p),
140 INIT_CK(NULL, "pll2", &clk_pll2), 140 INIT_CK(NULL, "pll2", &clk_pll2),
141 INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), 141 INIT_CK("ep93xx-ohci", NULL, &clk_usb_host),
142 INIT_CK(NULL, "m2p0", &clk_m2p0), 142 INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
143 INIT_CK(NULL, "m2p1", &clk_m2p1), 143 INIT_CK(NULL, "pwm_clk", &clk_pwm),
144 INIT_CK(NULL, "m2p2", &clk_m2p2), 144 INIT_CK(NULL, "m2p0", &clk_m2p0),
145 INIT_CK(NULL, "m2p3", &clk_m2p3), 145 INIT_CK(NULL, "m2p1", &clk_m2p1),
146 INIT_CK(NULL, "m2p4", &clk_m2p4), 146 INIT_CK(NULL, "m2p2", &clk_m2p2),
147 INIT_CK(NULL, "m2p5", &clk_m2p5), 147 INIT_CK(NULL, "m2p3", &clk_m2p3),
148 INIT_CK(NULL, "m2p6", &clk_m2p6), 148 INIT_CK(NULL, "m2p4", &clk_m2p4),
149 INIT_CK(NULL, "m2p7", &clk_m2p7), 149 INIT_CK(NULL, "m2p5", &clk_m2p5),
150 INIT_CK(NULL, "m2p8", &clk_m2p8), 150 INIT_CK(NULL, "m2p6", &clk_m2p6),
151 INIT_CK(NULL, "m2p9", &clk_m2p9), 151 INIT_CK(NULL, "m2p7", &clk_m2p7),
152 INIT_CK(NULL, "m2m0", &clk_m2m0), 152 INIT_CK(NULL, "m2p8", &clk_m2p8),
153 INIT_CK(NULL, "m2m1", &clk_m2m1), 153 INIT_CK(NULL, "m2p9", &clk_m2p9),
154 INIT_CK(NULL, "m2m0", &clk_m2m0),
155 INIT_CK(NULL, "m2m1", &clk_m2m1),
154}; 156};
155 157
156 158
@@ -160,9 +162,11 @@ int clk_enable(struct clk *clk)
160 u32 value; 162 u32 value;
161 163
162 value = __raw_readl(clk->enable_reg); 164 value = __raw_readl(clk->enable_reg);
165 value |= clk->enable_mask;
163 if (clk->sw_locked) 166 if (clk->sw_locked)
164 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 167 ep93xx_syscon_swlocked_write(value, clk->enable_reg);
165 __raw_writel(value | clk->enable_mask, clk->enable_reg); 168 else
169 __raw_writel(value, clk->enable_reg);
166 } 170 }
167 171
168 return 0; 172 return 0;
@@ -175,9 +179,11 @@ void clk_disable(struct clk *clk)
175 u32 value; 179 u32 value;
176 180
177 value = __raw_readl(clk->enable_reg); 181 value = __raw_readl(clk->enable_reg);
182 value &= ~clk->enable_mask;
178 if (clk->sw_locked) 183 if (clk->sw_locked)
179 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 184 ep93xx_syscon_swlocked_write(value, clk->enable_reg);
180 __raw_writel(value & ~clk->enable_mask, clk->enable_reg); 185 else
186 __raw_writel(value, clk->enable_reg);
181 } 187 }
182} 188}
183EXPORT_SYMBOL(clk_disable); 189EXPORT_SYMBOL(clk_disable);
@@ -202,6 +208,43 @@ unsigned long clk_get_rate(struct clk *clk)
202} 208}
203EXPORT_SYMBOL(clk_get_rate); 209EXPORT_SYMBOL(clk_get_rate);
204 210
211static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
212{
213 u32 val;
214 u32 div_bit;
215
216 val = __raw_readl(clk->enable_reg);
217
218 /*
219 * The Key Matrix and ADC clocks are configured using the same
220 * System Controller register. The clock used will be either
221 * 1/4 or 1/16 the external clock rate depending on the
222 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
223 * bit being set or cleared.
224 */
225 div_bit = clk->enable_mask >> 15;
226
227 if (rate == EP93XX_KEYTCHCLK_DIV4)
228 val |= div_bit;
229 else if (rate == EP93XX_KEYTCHCLK_DIV16)
230 val &= ~div_bit;
231 else
232 return -EINVAL;
233
234 ep93xx_syscon_swlocked_write(val, clk->enable_reg);
235 clk->rate = rate;
236 return 0;
237}
238
239int clk_set_rate(struct clk *clk, unsigned long rate)
240{
241 if (clk->set_rate)
242 return clk->set_rate(clk, rate);
243
244 return -EINVAL;
245}
246EXPORT_SYMBOL(clk_set_rate);
247
205 248
206static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; 249static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
207static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; 250static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 204dc5cbd0b8..16b92c37ec99 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -16,40 +16,24 @@
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/spinlock.h> 19#include <linux/platform_device.h>
20#include <linux/sched.h>
21#include <linux/interrupt.h> 20#include <linux/interrupt.h>
22#include <linux/serial.h>
23#include <linux/tty.h>
24#include <linux/bitops.h>
25#include <linux/serial_8250.h>
26#include <linux/serial_core.h>
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
30#include <linux/time.h>
31#include <linux/timex.h> 22#include <linux/timex.h>
32#include <linux/delay.h> 23#include <linux/io.h>
24#include <linux/gpio.h>
25#include <linux/leds.h>
33#include <linux/termios.h> 26#include <linux/termios.h>
34#include <linux/amba/bus.h> 27#include <linux/amba/bus.h>
35#include <linux/amba/serial.h> 28#include <linux/amba/serial.h>
36#include <linux/io.h>
37#include <linux/i2c.h> 29#include <linux/i2c.h>
38#include <linux/i2c-gpio.h> 30#include <linux/i2c-gpio.h>
39 31
40#include <asm/types.h>
41#include <asm/setup.h>
42#include <asm/memory.h>
43#include <mach/hardware.h> 32#include <mach/hardware.h>
44#include <asm/irq.h>
45#include <asm/system.h>
46#include <asm/tlbflush.h>
47#include <asm/pgtable.h>
48 33
49#include <asm/mach/map.h> 34#include <asm/mach/map.h>
50#include <asm/mach/time.h> 35#include <asm/mach/time.h>
51#include <asm/mach/irq.h> 36#include <asm/mach/irq.h>
52#include <mach/gpio.h>
53 37
54#include <asm/hardware/vic.h> 38#include <asm/hardware/vic.h>
55 39
@@ -98,7 +82,7 @@ void __init ep93xx_map_io(void)
98 */ 82 */
99static unsigned int last_jiffy_time; 83static unsigned int last_jiffy_time;
100 84
101#define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) 85#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
102 86
103static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) 87static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
104{ 88{
@@ -362,8 +346,8 @@ void __init ep93xx_init_irq(void)
362{ 346{
363 int gpio_irq; 347 int gpio_irq;
364 348
365 vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); 349 vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
366 vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); 350 vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
367 351
368 for (gpio_irq = gpio_to_irq(0); 352 for (gpio_irq = gpio_to_irq(0);
369 gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { 353 gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
@@ -385,6 +369,47 @@ void __init ep93xx_init_irq(void)
385 369
386 370
387/************************************************************************* 371/*************************************************************************
372 * EP93xx System Controller Software Locked register handling
373 *************************************************************************/
374
375/*
376 * syscon_swlock prevents anything else from writing to the syscon
377 * block while a software locked register is being written.
378 */
379static DEFINE_SPINLOCK(syscon_swlock);
380
381void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg)
382{
383 unsigned long flags;
384
385 spin_lock_irqsave(&syscon_swlock, flags);
386
387 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
388 __raw_writel(val, reg);
389
390 spin_unlock_irqrestore(&syscon_swlock, flags);
391}
392EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
393
394void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
395{
396 unsigned long flags;
397 unsigned int val;
398
399 spin_lock_irqsave(&syscon_swlock, flags);
400
401 val = __raw_readl(EP93XX_SYSCON_DEVCFG);
402 val |= set_bits;
403 val &= ~clear_bits;
404 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
405 __raw_writel(val, EP93XX_SYSCON_DEVCFG);
406
407 spin_unlock_irqrestore(&syscon_swlock, flags);
408}
409EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
410
411
412/*************************************************************************
388 * EP93xx peripheral handling 413 * EP93xx peripheral handling
389 *************************************************************************/ 414 *************************************************************************/
390#define EP93XX_UART_MCR_OFFSET (0x0100) 415#define EP93XX_UART_MCR_OFFSET (0x0100)
@@ -517,10 +542,8 @@ static struct platform_device ep93xx_eth_device = {
517 542
518void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) 543void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
519{ 544{
520 if (copy_addr) { 545 if (copy_addr)
521 memcpy(data->dev_addr, 546 memcpy_fromio(data->dev_addr, EP93XX_ETHERNET_BASE + 0x50, 6);
522 (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
523 }
524 547
525 ep93xx_eth_data = *data; 548 ep93xx_eth_data = *data;
526 platform_device_register(&ep93xx_eth_device); 549 platform_device_register(&ep93xx_eth_device);
@@ -546,19 +569,125 @@ void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
546 platform_device_register(&ep93xx_i2c_device); 569 platform_device_register(&ep93xx_i2c_device);
547} 570}
548 571
572
573/*************************************************************************
574 * EP93xx LEDs
575 *************************************************************************/
576static struct gpio_led ep93xx_led_pins[] = {
577 {
578 .name = "platform:grled",
579 .gpio = EP93XX_GPIO_LINE_GRLED,
580 }, {
581 .name = "platform:rdled",
582 .gpio = EP93XX_GPIO_LINE_RDLED,
583 },
584};
585
586static struct gpio_led_platform_data ep93xx_led_data = {
587 .num_leds = ARRAY_SIZE(ep93xx_led_pins),
588 .leds = ep93xx_led_pins,
589};
590
591static struct platform_device ep93xx_leds = {
592 .name = "leds-gpio",
593 .id = -1,
594 .dev = {
595 .platform_data = &ep93xx_led_data,
596 },
597};
598
599
600/*************************************************************************
601 * EP93xx pwm peripheral handling
602 *************************************************************************/
603static struct resource ep93xx_pwm0_resource[] = {
604 {
605 .start = EP93XX_PWM_PHYS_BASE,
606 .end = EP93XX_PWM_PHYS_BASE + 0x10 - 1,
607 .flags = IORESOURCE_MEM,
608 },
609};
610
611static struct platform_device ep93xx_pwm0_device = {
612 .name = "ep93xx-pwm",
613 .id = 0,
614 .num_resources = ARRAY_SIZE(ep93xx_pwm0_resource),
615 .resource = ep93xx_pwm0_resource,
616};
617
618static struct resource ep93xx_pwm1_resource[] = {
619 {
620 .start = EP93XX_PWM_PHYS_BASE + 0x20,
621 .end = EP93XX_PWM_PHYS_BASE + 0x30 - 1,
622 .flags = IORESOURCE_MEM,
623 },
624};
625
626static struct platform_device ep93xx_pwm1_device = {
627 .name = "ep93xx-pwm",
628 .id = 1,
629 .num_resources = ARRAY_SIZE(ep93xx_pwm1_resource),
630 .resource = ep93xx_pwm1_resource,
631};
632
633void __init ep93xx_register_pwm(int pwm0, int pwm1)
634{
635 if (pwm0)
636 platform_device_register(&ep93xx_pwm0_device);
637
638 /* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */
639 if (pwm1)
640 platform_device_register(&ep93xx_pwm1_device);
641}
642
643int ep93xx_pwm_acquire_gpio(struct platform_device *pdev)
644{
645 int err;
646
647 if (pdev->id == 0) {
648 err = 0;
649 } else if (pdev->id == 1) {
650 err = gpio_request(EP93XX_GPIO_LINE_EGPIO14,
651 dev_name(&pdev->dev));
652 if (err)
653 return err;
654 err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0);
655 if (err)
656 goto fail;
657
658 /* PWM 1 output on EGPIO[14] */
659 ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG);
660 } else {
661 err = -ENODEV;
662 }
663
664 return err;
665
666fail:
667 gpio_free(EP93XX_GPIO_LINE_EGPIO14);
668 return err;
669}
670EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio);
671
672void ep93xx_pwm_release_gpio(struct platform_device *pdev)
673{
674 if (pdev->id == 1) {
675 gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14);
676 gpio_free(EP93XX_GPIO_LINE_EGPIO14);
677
678 /* EGPIO[14] used for GPIO */
679 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG);
680 }
681}
682EXPORT_SYMBOL(ep93xx_pwm_release_gpio);
683
684
549extern void ep93xx_gpio_init(void); 685extern void ep93xx_gpio_init(void);
550 686
551void __init ep93xx_init_devices(void) 687void __init ep93xx_init_devices(void)
552{ 688{
553 unsigned int v; 689 /* Disallow access to MaverickCrunch initially */
554 690 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
555 /*
556 * Disallow access to MaverickCrunch initially.
557 */
558 v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
559 v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
560 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
561 __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
562 691
563 ep93xx_gpio_init(); 692 ep93xx_gpio_init();
564 693
@@ -568,4 +697,5 @@ void __init ep93xx_init_devices(void)
568 697
569 platform_device_register(&ep93xx_rtc_device); 698 platform_device_register(&ep93xx_rtc_device);
570 platform_device_register(&ep93xx_ohci_device); 699 platform_device_register(&ep93xx_ohci_device);
700 platform_device_register(&ep93xx_leds);
571} 701}
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index e9e45b92457e..73145ae5d3fa 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -26,18 +26,16 @@
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/mm.h>
30#include <linux/sched.h>
31#include <linux/interrupt.h>
32#include <linux/ioport.h>
33#include <linux/mtd/physmap.h>
34#include <linux/platform_device.h> 29#include <linux/platform_device.h>
35#include <linux/io.h>
36#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/mtd/physmap.h>
32
37#include <mach/hardware.h> 33#include <mach/hardware.h>
34
38#include <asm/mach-types.h> 35#include <asm/mach-types.h>
39#include <asm/mach/arch.h> 36#include <asm/mach/arch.h>
40 37
38
41static struct physmap_flash_data edb93xx_flash_data; 39static struct physmap_flash_data edb93xx_flash_data;
42 40
43static struct resource edb93xx_flash_resource = { 41static struct resource edb93xx_flash_resource = {
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index 3bad500b71b6..3da7ca816d19 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -12,18 +12,15 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/mm.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/mtd/physmap.h>
20#include <linux/platform_device.h> 15#include <linux/platform_device.h>
21#include <linux/io.h> 16#include <linux/mtd/physmap.h>
22#include <linux/i2c.h> 17
23#include <mach/hardware.h> 18#include <mach/hardware.h>
19
24#include <asm/mach-types.h> 20#include <asm/mach-types.h>
25#include <asm/mach/arch.h> 21#include <asm/mach/arch.h>
26 22
23
27static struct physmap_flash_data gesbc9312_flash_data = { 24static struct physmap_flash_data gesbc9312_flash_data = {
28 .width = 4, 25 .width = 4,
29}; 26};
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index 482cf3d2fbcd..1ea8871e03a9 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -17,15 +17,16 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/gpio.h>
21#include <linux/irq.h>
20 22
21#include <mach/ep93xx-regs.h> 23#include <mach/hardware.h>
22#include <asm/gpio.h>
23 24
24struct ep93xx_gpio_chip { 25struct ep93xx_gpio_chip {
25 struct gpio_chip chip; 26 struct gpio_chip chip;
26 27
27 unsigned int data_reg; 28 void __iomem *data_reg;
28 unsigned int data_dir_reg; 29 void __iomem *data_dir_reg;
29}; 30};
30 31
31#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) 32#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
@@ -111,15 +112,61 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
111{ 112{
112 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 113 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
113 u8 data_reg, data_dir_reg; 114 u8 data_reg, data_dir_reg;
114 int i; 115 int gpio, i;
115 116
116 data_reg = __raw_readb(ep93xx_chip->data_reg); 117 data_reg = __raw_readb(ep93xx_chip->data_reg);
117 data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg); 118 data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg);
118 119
119 for (i = 0; i < chip->ngpio; i++) 120 gpio = ep93xx_chip->chip.base;
120 seq_printf(s, "GPIO %s%d: %s %s\n", chip->label, i, 121 for (i = 0; i < chip->ngpio; i++, gpio++) {
121 (data_reg & (1 << i)) ? "set" : "clear", 122 int is_out = data_dir_reg & (1 << i);
122 (data_dir_reg & (1 << i)) ? "out" : "in"); 123
124 seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s",
125 chip->label, i, gpio,
126 gpiochip_is_requested(chip, i) ? : "",
127 is_out ? "out" : "in ",
128 (data_reg & (1 << i)) ? "hi" : "lo");
129
130 if (!is_out) {
131 int irq = gpio_to_irq(gpio);
132 struct irq_desc *desc = irq_desc + irq;
133
134 if (irq >= 0 && desc->action) {
135 char *trigger;
136
137 switch (desc->status & IRQ_TYPE_SENSE_MASK) {
138 case IRQ_TYPE_NONE:
139 trigger = "(default)";
140 break;
141 case IRQ_TYPE_EDGE_FALLING:
142 trigger = "edge-falling";
143 break;
144 case IRQ_TYPE_EDGE_RISING:
145 trigger = "edge-rising";
146 break;
147 case IRQ_TYPE_EDGE_BOTH:
148 trigger = "edge-both";
149 break;
150 case IRQ_TYPE_LEVEL_HIGH:
151 trigger = "level-high";
152 break;
153 case IRQ_TYPE_LEVEL_LOW:
154 trigger = "level-low";
155 break;
156 default:
157 trigger = "?trigger?";
158 break;
159 }
160
161 seq_printf(s, " irq-%d %s%s",
162 irq, trigger,
163 (desc->status & IRQ_WAKEUP)
164 ? " wakeup" : "");
165 }
166 }
167
168 seq_printf(s, "\n");
169 }
123} 170}
124 171
125#define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ 172#define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 967c079180db..ea78e908fc82 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -52,40 +52,43 @@
52#define EP93XX_AHB_VIRT_BASE 0xfef00000 52#define EP93XX_AHB_VIRT_BASE 0xfef00000
53#define EP93XX_AHB_SIZE 0x00100000 53#define EP93XX_AHB_SIZE 0x00100000
54 54
55#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x))
56
55#define EP93XX_APB_PHYS_BASE 0x80800000 57#define EP93XX_APB_PHYS_BASE 0x80800000
56#define EP93XX_APB_VIRT_BASE 0xfed00000 58#define EP93XX_APB_VIRT_BASE 0xfed00000
57#define EP93XX_APB_SIZE 0x00200000 59#define EP93XX_APB_SIZE 0x00200000
58 60
61#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x))
62
59 63
60/* AHB peripherals */ 64/* AHB peripherals */
61#define EP93XX_DMA_BASE ((void __iomem *) \ 65#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000)
62 (EP93XX_AHB_VIRT_BASE + 0x00000000))
63 66
64#define EP93XX_ETHERNET_BASE (EP93XX_AHB_VIRT_BASE + 0x00010000)
65#define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000) 67#define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000)
68#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000)
66 69
67#define EP93XX_USB_BASE (EP93XX_AHB_VIRT_BASE + 0x00020000)
68#define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) 70#define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000)
71#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
69 72
70#define EP93XX_RASTER_BASE (EP93XX_AHB_VIRT_BASE + 0x00030000) 73#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
71 74
72#define EP93XX_GRAPHICS_ACCEL_BASE (EP93XX_AHB_VIRT_BASE + 0x00040000) 75#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
73 76
74#define EP93XX_SDRAM_CONTROLLER_BASE (EP93XX_AHB_VIRT_BASE + 0x00060000) 77#define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000)
75 78
76#define EP93XX_PCMCIA_CONTROLLER_BASE (EP93XX_AHB_VIRT_BASE + 0x00080000) 79#define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000)
77 80
78#define EP93XX_BOOT_ROM_BASE (EP93XX_AHB_VIRT_BASE + 0x00090000) 81#define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000)
79 82
80#define EP93XX_IDE_BASE (EP93XX_AHB_VIRT_BASE + 0x000a0000) 83#define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000)
81 84
82#define EP93XX_VIC1_BASE (EP93XX_AHB_VIRT_BASE + 0x000b0000) 85#define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000)
83 86
84#define EP93XX_VIC2_BASE (EP93XX_AHB_VIRT_BASE + 0x000c0000) 87#define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000)
85 88
86 89
87/* APB peripherals */ 90/* APB peripherals */
88#define EP93XX_TIMER_BASE (EP93XX_APB_VIRT_BASE + 0x00010000) 91#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
89#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) 92#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
90#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) 93#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
91#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04) 94#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
@@ -102,11 +105,11 @@
102#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) 105#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
103#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) 106#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
104 107
105#define EP93XX_I2S_BASE (EP93XX_APB_VIRT_BASE + 0x00020000) 108#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
106 109
107#define EP93XX_SECURITY_BASE (EP93XX_APB_VIRT_BASE + 0x00030000) 110#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
108 111
109#define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000) 112#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
110#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) 113#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
111#define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c) 114#define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c)
112#define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50) 115#define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50)
@@ -124,32 +127,33 @@
124#define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8) 127#define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8)
125#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) 128#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
126 129
127#define EP93XX_AAC_BASE (EP93XX_APB_VIRT_BASE + 0x00080000) 130#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
128 131
129#define EP93XX_SPI_BASE (EP93XX_APB_VIRT_BASE + 0x000a0000) 132#define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000)
130 133
131#define EP93XX_IRDA_BASE (EP93XX_APB_VIRT_BASE + 0x000b0000) 134#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000)
132 135
133#define EP93XX_UART1_BASE (EP93XX_APB_VIRT_BASE + 0x000c0000)
134#define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000) 136#define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000)
137#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000)
135 138
136#define EP93XX_UART2_BASE (EP93XX_APB_VIRT_BASE + 0x000d0000)
137#define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000) 139#define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000)
140#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000)
138 141
139#define EP93XX_UART3_BASE (EP93XX_APB_VIRT_BASE + 0x000e0000)
140#define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000) 142#define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000)
143#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000)
141 144
142#define EP93XX_KEY_MATRIX_BASE (EP93XX_APB_VIRT_BASE + 0x000f0000) 145#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000)
143 146
144#define EP93XX_ADC_BASE (EP93XX_APB_VIRT_BASE + 0x00100000) 147#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000)
145#define EP93XX_TOUCHSCREEN_BASE (EP93XX_APB_VIRT_BASE + 0x00100000) 148#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000)
146 149
147#define EP93XX_PWM_BASE (EP93XX_APB_VIRT_BASE + 0x00110000) 150#define EP93XX_PWM_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00110000)
151#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000)
148 152
149#define EP93XX_RTC_BASE (EP93XX_APB_VIRT_BASE + 0x00120000)
150#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) 153#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000)
154#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000)
151 155
152#define EP93XX_SYSCON_BASE (EP93XX_APB_VIRT_BASE + 0x00130000) 156#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000)
153#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) 157#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x))
154#define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00) 158#define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00)
155#define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04) 159#define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04)
@@ -172,14 +176,45 @@
172#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) 176#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
173#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) 177#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20)
174#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) 178#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24)
175#define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) 179#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
176#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) 180#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
177#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) 181#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
178#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) 182#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29)
179#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) 183#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28)
184#define EP93XX_SYSCON_DEVCFG_GONK (1<<27)
185#define EP93XX_SYSCON_DEVCFG_TONG (1<<26)
186#define EP93XX_SYSCON_DEVCFG_MONG (1<<25)
187#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24)
188#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23)
189#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22)
190#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21)
191#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20)
192#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19)
193#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18)
194#define EP93XX_SYSCON_DEVCFG_TIN (1<<17)
195#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15)
196#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14)
197#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13)
198#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12)
199#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11)
200#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10)
201#define EP93XX_SYSCON_DEVCFG_PONG (1<<9)
202#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8)
203#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7)
204#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
205#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4)
206#define EP93XX_SYSCON_DEVCFG_RAS (1<<3)
207#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
208#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
209#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
210#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
211#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
212#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
213#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
214#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
180#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) 215#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
181 216
182#define EP93XX_WATCHDOG_BASE (EP93XX_APB_VIRT_BASE + 0x00140000) 217#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
183 218
184 219
185#endif 220#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h
index 2866297310b7..349fa7cb72d5 100644
--- a/arch/arm/mach-ep93xx/include/mach/hardware.h
+++ b/arch/arm/mach-ep93xx/include/mach/hardware.h
@@ -4,12 +4,23 @@
4#ifndef __ASM_ARCH_HARDWARE_H 4#ifndef __ASM_ARCH_HARDWARE_H
5#define __ASM_ARCH_HARDWARE_H 5#define __ASM_ARCH_HARDWARE_H
6 6
7#include "ep93xx-regs.h" 7#include <mach/ep93xx-regs.h>
8#include <mach/platform.h>
8 9
9#define pcibios_assign_all_busses() 0 10#define pcibios_assign_all_busses() 0
10 11
11#include "platform.h" 12/*
13 * The EP93xx has two external crystal oscillators. To generate the
14 * required high-frequency clocks, the processor uses two phase-locked-
15 * loops (PLLs) to multiply the incoming external clock signal to much
16 * higher frequencies that are then divided down by programmable dividers
17 * to produce the needed clocks. The PLLs operate independently of one
18 * another.
19 */
20#define EP93XX_EXT_CLK_RATE 14745600
21#define EP93XX_EXT_RTC_RATE 32768
12 22
13#include "ts72xx.h" 23#define EP93XX_KEYTCHCLK_DIV4 (EP93XX_EXT_CLK_RATE / 4)
24#define EP93XX_KEYTCHCLK_DIV16 (EP93XX_EXT_CLK_RATE / 16)
14 25
15#endif 26#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h
index fd5f081cc8b7..cebcc1c53d63 100644
--- a/arch/arm/mach-ep93xx/include/mach/io.h
+++ b/arch/arm/mach-ep93xx/include/mach/io.h
@@ -1,8 +1,21 @@
1/* 1/*
2 * arch/arm/mach-ep93xx/include/mach/io.h 2 * arch/arm/mach-ep93xx/include/mach/io.h
3 */ 3 */
4#ifndef __ASM_MACH_IO_H
5#define __ASM_MACH_IO_H
4 6
5#define IO_SPACE_LIMIT 0xffffffff 7#define IO_SPACE_LIMIT 0xffffffff
6 8
7#define __io(p) __typesafe_io(p) 9#define __io(p) __typesafe_io(p)
8#define __mem_pci(p) (p) 10#define __mem_pci(p) (p)
11
12/*
13 * A typesafe __io() variation for variable initialisers
14 */
15#ifdef __ASSEMBLER__
16#define IOMEM(p) p
17#else
18#define IOMEM(p) ((void __iomem __force *)(p))
19#endif
20
21#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 05f0f4f2f3ce..5f5fa6574d34 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -5,6 +5,7 @@
5#ifndef __ASSEMBLY__ 5#ifndef __ASSEMBLY__
6 6
7struct i2c_board_info; 7struct i2c_board_info;
8struct platform_device;
8 9
9struct ep93xx_eth_data 10struct ep93xx_eth_data
10{ 11{
@@ -15,8 +16,27 @@ struct ep93xx_eth_data
15void ep93xx_map_io(void); 16void ep93xx_map_io(void);
16void ep93xx_init_irq(void); 17void ep93xx_init_irq(void);
17void ep93xx_init_time(unsigned long); 18void ep93xx_init_time(unsigned long);
19
20/* EP93xx System Controller software locked register write */
21void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
22void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
23
24static inline void ep93xx_devcfg_set_bits(unsigned int bits)
25{
26 ep93xx_devcfg_set_clear(bits, 0x00);
27}
28
29static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
30{
31 ep93xx_devcfg_set_clear(0x00, bits);
32}
33
18void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); 34void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
19void ep93xx_register_i2c(struct i2c_board_info *devices, int num); 35void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
36void ep93xx_register_pwm(int pwm0, int pwm1);
37int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
38void ep93xx_pwm_release_gpio(struct platform_device *pdev);
39
20void ep93xx_init_devices(void); 40void ep93xx_init_devices(void);
21extern struct sys_timer ep93xx_timer; 41extern struct sys_timer ep93xx_timer;
22 42
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
index ed8f35e4f068..6d661fe9d66c 100644
--- a/arch/arm/mach-ep93xx/include/mach/system.h
+++ b/arch/arm/mach-ep93xx/include/mach/system.h
@@ -11,15 +11,13 @@ static inline void arch_idle(void)
11 11
12static inline void arch_reset(char mode, const char *cmd) 12static inline void arch_reset(char mode, const char *cmd)
13{ 13{
14 u32 devicecfg;
15
16 local_irq_disable(); 14 local_irq_disable();
17 15
18 devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); 16 /*
19 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 17 * Set then clear the SWRST bit to initiate a software reset
20 __raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); 18 */
21 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 19 ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST);
22 __raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); 20 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST);
23 21
24 while (1) 22 while (1)
25 ; 23 ;
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 411734422c1d..3bd934e9a7f1 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -67,7 +67,6 @@
67 67
68 68
69#ifndef __ASSEMBLY__ 69#ifndef __ASSEMBLY__
70#include <linux/io.h>
71 70
72static inline int board_is_ts7200(void) 71static inline int board_is_ts7200(void)
73{ 72{
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 15d6815d78c4..0a313e82fb74 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -9,21 +9,16 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/ioport.h>
15#include <linux/kernel.h> 12#include <linux/kernel.h>
16#include <linux/mm.h> 13#include <linux/init.h>
17#include <linux/platform_device.h> 14#include <linux/platform_device.h>
18#include <linux/sched.h>
19#include <linux/io.h>
20#include <linux/i2c.h>
21#include <linux/mtd/physmap.h> 15#include <linux/mtd/physmap.h>
22 16
23#include <mach/hardware.h> 17#include <mach/hardware.h>
24 18
25#include <asm/mach/arch.h>
26#include <asm/mach-types.h> 19#include <asm/mach-types.h>
20#include <asm/mach/arch.h>
21
27 22
28static struct ep93xx_eth_data micro9_eth_data = { 23static struct ep93xx_eth_data micro9_eth_data = {
29 .phy_id = 0x1f, 24 .phy_id = 0x1f,
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index aaf1371412af..259f7822ba52 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -12,19 +12,18 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/mm.h>
16#include <linux/sched.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/mtd/physmap.h>
20#include <linux/platform_device.h> 15#include <linux/platform_device.h>
21#include <linux/m48t86.h>
22#include <linux/io.h> 16#include <linux/io.h>
23#include <linux/i2c.h> 17#include <linux/m48t86.h>
18#include <linux/mtd/physmap.h>
19
24#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <mach/ts72xx.h>
22
25#include <asm/mach-types.h> 23#include <asm/mach-types.h>
26#include <asm/mach/arch.h>
27#include <asm/mach/map.h> 24#include <asm/mach/map.h>
25#include <asm/mach/arch.h>
26
28 27
29static struct map_desc ts72xx_io_desc[] __initdata = { 28static struct map_desc ts72xx_io_desc[] __initdata = {
30 { 29 {
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h
index 1251319ef9ae..d795642fad22 100644
--- a/arch/arm/mach-integrator/include/mach/hardware.h
+++ b/arch/arm/mach-integrator/include/mach/hardware.h
@@ -36,8 +36,12 @@
36#define PCIO_BASE PCI_IO_VADDR 36#define PCIO_BASE PCI_IO_VADDR
37#define PCIMEM_BASE PCI_MEMORY_VADDR 37#define PCIMEM_BASE PCI_MEMORY_VADDR
38 38
39#ifdef CONFIG_MMU
39/* macro to get at IO space when running virtually */ 40/* macro to get at IO space when running virtually */
40#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) 41#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE)
42#else
43#define IO_ADDRESS(x) (x)
44#endif
41 45
42#define pcibios_assign_all_busses() 1 46#define pcibios_assign_all_busses() 1
43 47
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 4ac04055c2ea..2a318eba1b07 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -49,14 +49,14 @@
49 49
50#define INTCP_PA_CLCD_BASE 0xc0000000 50#define INTCP_PA_CLCD_BASE 0xc0000000
51 51
52#define INTCP_VA_CIC_BASE 0xf1000040 52#define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40
53#define INTCP_VA_PIC_BASE 0xf1400000 53#define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
54#define INTCP_VA_SIC_BASE 0xfca00000 54#define INTCP_VA_SIC_BASE IO_ADDRESS(0xca000000)
55 55
56#define INTCP_PA_ETH_BASE 0xc8000000 56#define INTCP_PA_ETH_BASE 0xc8000000
57#define INTCP_ETH_SIZE 0x10 57#define INTCP_ETH_SIZE 0x10
58 58
59#define INTCP_VA_CTRL_BASE 0xfcb00000 59#define INTCP_VA_CTRL_BASE IO_ADDRESS(0xcb000000)
60#define INTCP_FLASHPROG 0x04 60#define INTCP_FLASHPROG 0x04
61#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) 61#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0)
62#define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) 62#define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1)
@@ -121,12 +121,12 @@ static struct map_desc intcp_io_desc[] __initdata = {
121 .length = SZ_4K, 121 .length = SZ_4K,
122 .type = MT_DEVICE 122 .type = MT_DEVICE
123 }, { 123 }, {
124 .virtual = 0xfca00000, 124 .virtual = IO_ADDRESS(0xca000000),
125 .pfn = __phys_to_pfn(0xca000000), 125 .pfn = __phys_to_pfn(0xca000000),
126 .length = SZ_4K, 126 .length = SZ_4K,
127 .type = MT_DEVICE 127 .type = MT_DEVICE
128 }, { 128 }, {
129 .virtual = 0xfcb00000, 129 .virtual = IO_ADDRESS(0xcb000000),
130 .pfn = __phys_to_pfn(0xcb000000), 130 .pfn = __phys_to_pfn(0xcb000000),
131 .length = SZ_4K, 131 .length = SZ_4K,
132 .type = MT_DEVICE 132 .type = MT_DEVICE
@@ -394,8 +394,8 @@ static struct platform_device *intcp_devs[] __initdata = {
394 */ 394 */
395static unsigned int mmc_status(struct device *dev) 395static unsigned int mmc_status(struct device *dev)
396{ 396{
397 unsigned int status = readl(0xfca00004); 397 unsigned int status = readl(IO_ADDRESS(0xca000000) + 4);
398 writel(8, 0xfcb00008); 398 writel(8, IO_ADDRESS(0xcb000000) + 8);
399 399
400 return status & 8; 400 return status & 8;
401} 401}
@@ -403,6 +403,8 @@ static unsigned int mmc_status(struct device *dev)
403static struct mmc_platform_data mmc_data = { 403static struct mmc_platform_data mmc_data = {
404 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 404 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
405 .status = mmc_status, 405 .status = mmc_status,
406 .gpio_wp = -1,
407 .gpio_cd = -1,
406}; 408};
407 409
408static struct amba_device mmc_device = { 410static struct amba_device mmc_device = {
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 1e93dfee7543..5083f03e9b5e 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -416,6 +416,7 @@ static struct clocksource clocksource_ixp4xx = {
416}; 416};
417 417
418unsigned long ixp4xx_timer_freq = FREQ; 418unsigned long ixp4xx_timer_freq = FREQ;
419EXPORT_SYMBOL(ixp4xx_timer_freq);
419static int __init ixp4xx_clocksource_init(void) 420static int __init ixp4xx_clocksource_init(void)
420{ 421{
421 clocksource_ixp4xx.mult = 422 clocksource_ixp4xx.mult =
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 25100f7acf4c..0aca451b216d 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -38,6 +38,12 @@ config MACH_TS219
38 Say 'Y' here if you want your kernel to support the 38 Say 'Y' here if you want your kernel to support the
39 QNAP TS-119 and TS-219 Turbo NAS devices. 39 QNAP TS-119 and TS-219 Turbo NAS devices.
40 40
41config MACH_OPENRD_BASE
42 bool "Marvell OpenRD Base Board"
43 help
44 Say 'Y' here if you want your kernel to support the
45 Marvell OpenRD Base Board.
46
41endmenu 47endmenu
42 48
43endif 49endif
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 9dd680e964d6..80ab0ec90ee1 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o
6obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o 6obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
7obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o 7obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
8obj-$(CONFIG_MACH_TS219) += ts219-setup.o 8obj-$(CONFIG_MACH_TS219) += ts219-setup.o
9obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o
9 10
10obj-$(CONFIG_CPU_IDLE) += cpuidle.o 11obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 0f6919838011..0acb61f3c10b 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -838,7 +838,8 @@ int __init kirkwood_find_tclk(void)
838 u32 dev, rev; 838 u32 dev, rev;
839 839
840 kirkwood_pcie_id(&dev, &rev); 840 kirkwood_pcie_id(&dev, &rev);
841 if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0) 841 if (dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 ||
842 rev == MV88F6281_REV_A1))
842 return 200000000; 843 return 200000000;
843 844
844 return 166666667; 845 return 166666667;
@@ -872,6 +873,8 @@ static char * __init kirkwood_id(void)
872 return "MV88F6281-Z0"; 873 return "MV88F6281-Z0";
873 else if (rev == MV88F6281_REV_A0) 874 else if (rev == MV88F6281_REV_A0)
874 return "MV88F6281-A0"; 875 return "MV88F6281-A0";
876 else if (rev == MV88F6281_REV_A1)
877 return "MV88F6281-A1";
875 else 878 else
876 return "MV88F6281-Rev-Unsupported"; 879 return "MV88F6281-Rev-Unsupported";
877 } else if (dev == MV88F6192_DEV_ID) { 880 } else if (dev == MV88F6192_DEV_ID) {
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index 07af858814a0..54c132731d2d 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -101,6 +101,7 @@
101#define MV88F6281_DEV_ID 0x6281 101#define MV88F6281_DEV_ID 0x6281
102#define MV88F6281_REV_Z0 0 102#define MV88F6281_REV_Z0 0
103#define MV88F6281_REV_A0 2 103#define MV88F6281_REV_A0 2
104#define MV88F6281_REV_A1 3
104 105
105#define MV88F6192_DEV_ID 0x6192 106#define MV88F6192_DEV_ID 0x6192
106#define MV88F6192_REV_Z0 0 107#define MV88F6192_REV_Z0 0
diff --git a/arch/arm/mach-kirkwood/openrd_base-setup.c b/arch/arm/mach-kirkwood/openrd_base-setup.c
new file mode 100644
index 000000000000..947dfb8cd5b2
--- /dev/null
+++ b/arch/arm/mach-kirkwood/openrd_base-setup.c
@@ -0,0 +1,84 @@
1/*
2 * arch/arm/mach-kirkwood/openrd_base-setup.c
3 *
4 * Marvell OpenRD Base Board Setup
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/mtd/partitions.h>
15#include <linux/ata_platform.h>
16#include <linux/mv643xx_eth.h>
17#include <asm/mach-types.h>
18#include <asm/mach/arch.h>
19#include <mach/kirkwood.h>
20#include <plat/mvsdio.h>
21#include "common.h"
22#include "mpp.h"
23
24static struct mtd_partition openrd_base_nand_parts[] = {
25 {
26 .name = "u-boot",
27 .offset = 0,
28 .size = SZ_1M
29 }, {
30 .name = "uImage",
31 .offset = MTDPART_OFS_NXTBLK,
32 .size = SZ_4M
33 }, {
34 .name = "root",
35 .offset = MTDPART_OFS_NXTBLK,
36 .size = MTDPART_SIZ_FULL
37 },
38};
39
40static struct mv643xx_eth_platform_data openrd_base_ge00_data = {
41 .phy_addr = MV643XX_ETH_PHY_ADDR(8),
42};
43
44static struct mv_sata_platform_data openrd_base_sata_data = {
45 .n_ports = 2,
46};
47
48static struct mvsdio_platform_data openrd_base_mvsdio_data = {
49 .gpio_card_detect = 29, /* MPP29 used as SD card detect */
50};
51
52static unsigned int openrd_base_mpp_config[] __initdata = {
53 MPP29_GPIO,
54 0
55};
56
57static void __init openrd_base_init(void)
58{
59 /*
60 * Basic setup. Needs to be called early.
61 */
62 kirkwood_init();
63 kirkwood_mpp_conf(openrd_base_mpp_config);
64
65 kirkwood_uart0_init();
66 kirkwood_nand_init(ARRAY_AND_SIZE(openrd_base_nand_parts), 25);
67
68 kirkwood_ehci_init();
69
70 kirkwood_ge00_init(&openrd_base_ge00_data);
71 kirkwood_sata_init(&openrd_base_sata_data);
72 kirkwood_sdio_init(&openrd_base_mvsdio_data);
73}
74
75MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
76 /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
77 .phys_io = KIRKWOOD_REGS_PHYS_BASE,
78 .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
79 .boot_params = 0x00000100,
80 .init_machine = openrd_base_init,
81 .map_io = kirkwood_map_io,
82 .init_irq = kirkwood_init_irq,
83 .timer = &kirkwood_timer,
84MACHINE_END
diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c
index 0d0f306851d0..d1b588519ad2 100644
--- a/arch/arm/mach-mx1/clock.c
+++ b/arch/arm/mach-mx1/clock.c
@@ -18,11 +18,14 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/list.h>
21#include <linux/math64.h> 22#include <linux/math64.h>
22#include <linux/err.h> 23#include <linux/err.h>
23#include <linux/clk.h> 24#include <linux/clk.h>
24#include <linux/io.h> 25#include <linux/io.h>
25 26
27#include <asm/clkdev.h>
28
26#include <mach/clock.h> 29#include <mach/clock.h>
27#include <mach/hardware.h> 30#include <mach/hardware.h>
28#include <mach/common.h> 31#include <mach/common.h>
@@ -94,7 +97,6 @@ static unsigned long clk16m_get_rate(struct clk *clk)
94} 97}
95 98
96static struct clk clk16m = { 99static struct clk clk16m = {
97 .name = "CLK16M",
98 .get_rate = clk16m_get_rate, 100 .get_rate = clk16m_get_rate,
99 .enable = _clk_enable, 101 .enable = _clk_enable,
100 .enable_reg = CCM_CSCR, 102 .enable_reg = CCM_CSCR,
@@ -111,7 +113,6 @@ static unsigned long clk32_get_rate(struct clk *clk)
111} 113}
112 114
113static struct clk clk32 = { 115static struct clk clk32 = {
114 .name = "CLK32",
115 .get_rate = clk32_get_rate, 116 .get_rate = clk32_get_rate,
116}; 117};
117 118
@@ -121,7 +122,6 @@ static unsigned long clk32_premult_get_rate(struct clk *clk)
121} 122}
122 123
123static struct clk clk32_premult = { 124static struct clk clk32_premult = {
124 .name = "CLK32_premultiplier",
125 .parent = &clk32, 125 .parent = &clk32,
126 .get_rate = clk32_premult_get_rate, 126 .get_rate = clk32_premult_get_rate,
127}; 127};
@@ -156,7 +156,6 @@ static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
156} 156}
157 157
158static struct clk prem_clk = { 158static struct clk prem_clk = {
159 .name = "prem_clk",
160 .set_parent = prem_clk_set_parent, 159 .set_parent = prem_clk_set_parent,
161}; 160};
162 161
@@ -167,7 +166,6 @@ static unsigned long system_clk_get_rate(struct clk *clk)
167} 166}
168 167
169static struct clk system_clk = { 168static struct clk system_clk = {
170 .name = "system_clk",
171 .parent = &prem_clk, 169 .parent = &prem_clk,
172 .get_rate = system_clk_get_rate, 170 .get_rate = system_clk_get_rate,
173}; 171};
@@ -179,7 +177,6 @@ static unsigned long mcu_clk_get_rate(struct clk *clk)
179} 177}
180 178
181static struct clk mcu_clk = { 179static struct clk mcu_clk = {
182 .name = "mcu_clk",
183 .parent = &clk32_premult, 180 .parent = &clk32_premult,
184 .get_rate = mcu_clk_get_rate, 181 .get_rate = mcu_clk_get_rate,
185}; 182};
@@ -195,7 +192,6 @@ static unsigned long fclk_get_rate(struct clk *clk)
195} 192}
196 193
197static struct clk fclk = { 194static struct clk fclk = {
198 .name = "fclk",
199 .parent = &mcu_clk, 195 .parent = &mcu_clk,
200 .get_rate = fclk_get_rate, 196 .get_rate = fclk_get_rate,
201}; 197};
@@ -238,7 +234,6 @@ static int hclk_set_rate(struct clk *clk, unsigned long rate)
238} 234}
239 235
240static struct clk hclk = { 236static struct clk hclk = {
241 .name = "hclk",
242 .parent = &system_clk, 237 .parent = &system_clk,
243 .get_rate = hclk_get_rate, 238 .get_rate = hclk_get_rate,
244 .round_rate = hclk_round_rate, 239 .round_rate = hclk_round_rate,
@@ -280,7 +275,6 @@ static int clk48m_set_rate(struct clk *clk, unsigned long rate)
280} 275}
281 276
282static struct clk clk48m = { 277static struct clk clk48m = {
283 .name = "CLK48M",
284 .parent = &system_clk, 278 .parent = &system_clk,
285 .get_rate = clk48m_get_rate, 279 .get_rate = clk48m_get_rate,
286 .round_rate = clk48m_round_rate, 280 .round_rate = clk48m_round_rate,
@@ -400,21 +394,18 @@ static int perclk3_set_rate(struct clk *clk, unsigned long rate)
400 394
401static struct clk perclk[] = { 395static struct clk perclk[] = {
402 { 396 {
403 .name = "perclk",
404 .id = 0, 397 .id = 0,
405 .parent = &system_clk, 398 .parent = &system_clk,
406 .get_rate = perclk1_get_rate, 399 .get_rate = perclk1_get_rate,
407 .round_rate = perclk1_round_rate, 400 .round_rate = perclk1_round_rate,
408 .set_rate = perclk1_set_rate, 401 .set_rate = perclk1_set_rate,
409 }, { 402 }, {
410 .name = "perclk",
411 .id = 1, 403 .id = 1,
412 .parent = &system_clk, 404 .parent = &system_clk,
413 .get_rate = perclk2_get_rate, 405 .get_rate = perclk2_get_rate,
414 .round_rate = perclk2_round_rate, 406 .round_rate = perclk2_round_rate,
415 .set_rate = perclk2_set_rate, 407 .set_rate = perclk2_set_rate,
416 }, { 408 }, {
417 .name = "perclk",
418 .id = 2, 409 .id = 2,
419 .parent = &system_clk, 410 .parent = &system_clk,
420 .get_rate = perclk3_get_rate, 411 .get_rate = perclk3_get_rate,
@@ -457,12 +448,10 @@ static int clko_set_parent(struct clk *clk, struct clk *parent)
457} 448}
458 449
459static struct clk clko_clk = { 450static struct clk clko_clk = {
460 .name = "clko_clk",
461 .set_parent = clko_set_parent, 451 .set_parent = clko_set_parent,
462}; 452};
463 453
464static struct clk dma_clk = { 454static struct clk dma_clk = {
465 .name = "dma",
466 .parent = &hclk, 455 .parent = &hclk,
467 .round_rate = _clk_parent_round_rate, 456 .round_rate = _clk_parent_round_rate,
468 .set_rate = _clk_parent_set_rate, 457 .set_rate = _clk_parent_set_rate,
@@ -473,7 +462,6 @@ static struct clk dma_clk = {
473}; 462};
474 463
475static struct clk csi_clk = { 464static struct clk csi_clk = {
476 .name = "csi_clk",
477 .parent = &hclk, 465 .parent = &hclk,
478 .round_rate = _clk_parent_round_rate, 466 .round_rate = _clk_parent_round_rate,
479 .set_rate = _clk_parent_set_rate, 467 .set_rate = _clk_parent_set_rate,
@@ -484,7 +472,6 @@ static struct clk csi_clk = {
484}; 472};
485 473
486static struct clk mma_clk = { 474static struct clk mma_clk = {
487 .name = "mma_clk",
488 .parent = &hclk, 475 .parent = &hclk,
489 .round_rate = _clk_parent_round_rate, 476 .round_rate = _clk_parent_round_rate,
490 .set_rate = _clk_parent_set_rate, 477 .set_rate = _clk_parent_set_rate,
@@ -495,7 +482,6 @@ static struct clk mma_clk = {
495}; 482};
496 483
497static struct clk usbd_clk = { 484static struct clk usbd_clk = {
498 .name = "usbd_clk",
499 .parent = &clk48m, 485 .parent = &clk48m,
500 .round_rate = _clk_parent_round_rate, 486 .round_rate = _clk_parent_round_rate,
501 .set_rate = _clk_parent_set_rate, 487 .set_rate = _clk_parent_set_rate,
@@ -506,99 +492,85 @@ static struct clk usbd_clk = {
506}; 492};
507 493
508static struct clk gpt_clk = { 494static struct clk gpt_clk = {
509 .name = "gpt_clk",
510 .parent = &perclk[0], 495 .parent = &perclk[0],
511 .round_rate = _clk_parent_round_rate, 496 .round_rate = _clk_parent_round_rate,
512 .set_rate = _clk_parent_set_rate, 497 .set_rate = _clk_parent_set_rate,
513}; 498};
514 499
515static struct clk uart_clk = { 500static struct clk uart_clk = {
516 .name = "uart",
517 .parent = &perclk[0], 501 .parent = &perclk[0],
518 .round_rate = _clk_parent_round_rate, 502 .round_rate = _clk_parent_round_rate,
519 .set_rate = _clk_parent_set_rate, 503 .set_rate = _clk_parent_set_rate,
520}; 504};
521 505
522static struct clk i2c_clk = { 506static struct clk i2c_clk = {
523 .name = "i2c_clk",
524 .parent = &hclk, 507 .parent = &hclk,
525 .round_rate = _clk_parent_round_rate, 508 .round_rate = _clk_parent_round_rate,
526 .set_rate = _clk_parent_set_rate, 509 .set_rate = _clk_parent_set_rate,
527}; 510};
528 511
529static struct clk spi_clk = { 512static struct clk spi_clk = {
530 .name = "spi_clk",
531 .parent = &perclk[1], 513 .parent = &perclk[1],
532 .round_rate = _clk_parent_round_rate, 514 .round_rate = _clk_parent_round_rate,
533 .set_rate = _clk_parent_set_rate, 515 .set_rate = _clk_parent_set_rate,
534}; 516};
535 517
536static struct clk sdhc_clk = { 518static struct clk sdhc_clk = {
537 .name = "sdhc_clk",
538 .parent = &perclk[1], 519 .parent = &perclk[1],
539 .round_rate = _clk_parent_round_rate, 520 .round_rate = _clk_parent_round_rate,
540 .set_rate = _clk_parent_set_rate, 521 .set_rate = _clk_parent_set_rate,
541}; 522};
542 523
543static struct clk lcdc_clk = { 524static struct clk lcdc_clk = {
544 .name = "lcdc_clk",
545 .parent = &perclk[1], 525 .parent = &perclk[1],
546 .round_rate = _clk_parent_round_rate, 526 .round_rate = _clk_parent_round_rate,
547 .set_rate = _clk_parent_set_rate, 527 .set_rate = _clk_parent_set_rate,
548}; 528};
549 529
550static struct clk mshc_clk = { 530static struct clk mshc_clk = {
551 .name = "mshc_clk",
552 .parent = &hclk, 531 .parent = &hclk,
553 .round_rate = _clk_parent_round_rate, 532 .round_rate = _clk_parent_round_rate,
554 .set_rate = _clk_parent_set_rate, 533 .set_rate = _clk_parent_set_rate,
555}; 534};
556 535
557static struct clk ssi_clk = { 536static struct clk ssi_clk = {
558 .name = "ssi_clk",
559 .parent = &perclk[2], 537 .parent = &perclk[2],
560 .round_rate = _clk_parent_round_rate, 538 .round_rate = _clk_parent_round_rate,
561 .set_rate = _clk_parent_set_rate, 539 .set_rate = _clk_parent_set_rate,
562}; 540};
563 541
564static struct clk rtc_clk = { 542static struct clk rtc_clk = {
565 .name = "rtc_clk",
566 .parent = &clk32, 543 .parent = &clk32,
567}; 544};
568 545
569static struct clk *mxc_clks[] = { 546#define _REGISTER_CLOCK(d, n, c) \
570 &clk16m, 547 { \
571 &clk32, 548 .dev_id = d, \
572 &clk32_premult, 549 .con_id = n, \
573 &prem_clk, 550 .clk = &c, \
574 &system_clk, 551 },
575 &mcu_clk, 552static struct clk_lookup lookups[] __initdata = {
576 &fclk, 553 _REGISTER_CLOCK(NULL, "dma", dma_clk)
577 &hclk, 554 _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
578 &clk48m, 555 _REGISTER_CLOCK(NULL, "mma", mma_clk)
579 &perclk[0], 556 _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
580 &perclk[1], 557 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
581 &perclk[2], 558 _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk)
582 &clko_clk, 559 _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
583 &dma_clk, 560 _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
584 &csi_clk, 561 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
585 &mma_clk, 562 _REGISTER_CLOCK("spi_imx.0", NULL, spi_clk)
586 &usbd_clk, 563 _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
587 &gpt_clk, 564 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
588 &uart_clk, 565 _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
589 &i2c_clk, 566 _REGISTER_CLOCK(NULL, "ssi", ssi_clk)
590 &spi_clk, 567 _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
591 &sdhc_clk,
592 &lcdc_clk,
593 &mshc_clk,
594 &ssi_clk,
595 &rtc_clk,
596}; 568};
597 569
598int __init mx1_clocks_init(unsigned long fref) 570int __init mx1_clocks_init(unsigned long fref)
599{ 571{
600 struct clk **clkp;
601 unsigned int reg; 572 unsigned int reg;
573 int i;
602 574
603 /* disable clocks we are able to */ 575 /* disable clocks we are able to */
604 __raw_writel(0, SCM_GCCR); 576 __raw_writel(0, SCM_GCCR);
@@ -620,13 +592,13 @@ int __init mx1_clocks_init(unsigned long fref)
620 reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET; 592 reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
621 clko_clk.parent = (struct clk *)clko_clocks[reg]; 593 clko_clk.parent = (struct clk *)clko_clocks[reg];
622 594
623 for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) 595 for (i = 0; i < ARRAY_SIZE(lookups); i++)
624 clk_register(*clkp); 596 clkdev_add(&lookups[i]);
625 597
626 clk_enable(&hclk); 598 clk_enable(&hclk);
627 clk_enable(&fclk); 599 clk_enable(&fclk);
628 600
629 mxc_timer_init(&gpt_clk); 601 mxc_timer_init(&gpt_clk, IO_ADDRESS(TIM1_BASE_ADDR), TIM1_INT);
630 602
631 return 0; 603 return 0;
632} 604}
diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c
index 76d1ffb48079..b6be29d1cb08 100644
--- a/arch/arm/mach-mx1/devices.c
+++ b/arch/arm/mach-mx1/devices.c
@@ -29,12 +29,11 @@
29#include "devices.h" 29#include "devices.h"
30 30
31static struct resource imx_csi_resources[] = { 31static struct resource imx_csi_resources[] = {
32 [0] = { 32 {
33 .start = 0x00224000, 33 .start = 0x00224000,
34 .end = 0x00224010, 34 .end = 0x00224010,
35 .flags = IORESOURCE_MEM, 35 .flags = IORESOURCE_MEM,
36 }, 36 }, {
37 [1] = {
38 .start = CSI_INT, 37 .start = CSI_INT,
39 .end = CSI_INT, 38 .end = CSI_INT,
40 .flags = IORESOURCE_IRQ, 39 .flags = IORESOURCE_IRQ,
@@ -55,12 +54,11 @@ struct platform_device imx_csi_device = {
55}; 54};
56 55
57static struct resource imx_i2c_resources[] = { 56static struct resource imx_i2c_resources[] = {
58 [0] = { 57 {
59 .start = 0x00217000, 58 .start = 0x00217000,
60 .end = 0x00217010, 59 .end = 0x00217010,
61 .flags = IORESOURCE_MEM, 60 .flags = IORESOURCE_MEM,
62 }, 61 }, {
63 [1] = {
64 .start = I2C_INT, 62 .start = I2C_INT,
65 .end = I2C_INT, 63 .end = I2C_INT,
66 .flags = IORESOURCE_IRQ, 64 .flags = IORESOURCE_IRQ,
@@ -75,22 +73,19 @@ struct platform_device imx_i2c_device = {
75}; 73};
76 74
77static struct resource imx_uart1_resources[] = { 75static struct resource imx_uart1_resources[] = {
78 [0] = { 76 {
79 .start = UART1_BASE_ADDR, 77 .start = UART1_BASE_ADDR,
80 .end = UART1_BASE_ADDR + 0xD0, 78 .end = UART1_BASE_ADDR + 0xD0,
81 .flags = IORESOURCE_MEM, 79 .flags = IORESOURCE_MEM,
82 }, 80 }, {
83 [1] = {
84 .start = UART1_MINT_RX, 81 .start = UART1_MINT_RX,
85 .end = UART1_MINT_RX, 82 .end = UART1_MINT_RX,
86 .flags = IORESOURCE_IRQ, 83 .flags = IORESOURCE_IRQ,
87 }, 84 }, {
88 [2] = {
89 .start = UART1_MINT_TX, 85 .start = UART1_MINT_TX,
90 .end = UART1_MINT_TX, 86 .end = UART1_MINT_TX,
91 .flags = IORESOURCE_IRQ, 87 .flags = IORESOURCE_IRQ,
92 }, 88 }, {
93 [3] = {
94 .start = UART1_MINT_RTS, 89 .start = UART1_MINT_RTS,
95 .end = UART1_MINT_RTS, 90 .end = UART1_MINT_RTS,
96 .flags = IORESOURCE_IRQ, 91 .flags = IORESOURCE_IRQ,
@@ -105,22 +100,19 @@ struct platform_device imx_uart1_device = {
105}; 100};
106 101
107static struct resource imx_uart2_resources[] = { 102static struct resource imx_uart2_resources[] = {
108 [0] = { 103 {
109 .start = UART2_BASE_ADDR, 104 .start = UART2_BASE_ADDR,
110 .end = UART2_BASE_ADDR + 0xD0, 105 .end = UART2_BASE_ADDR + 0xD0,
111 .flags = IORESOURCE_MEM, 106 .flags = IORESOURCE_MEM,
112 }, 107 }, {
113 [1] = {
114 .start = UART2_MINT_RX, 108 .start = UART2_MINT_RX,
115 .end = UART2_MINT_RX, 109 .end = UART2_MINT_RX,
116 .flags = IORESOURCE_IRQ, 110 .flags = IORESOURCE_IRQ,
117 }, 111 }, {
118 [2] = {
119 .start = UART2_MINT_TX, 112 .start = UART2_MINT_TX,
120 .end = UART2_MINT_TX, 113 .end = UART2_MINT_TX,
121 .flags = IORESOURCE_IRQ, 114 .flags = IORESOURCE_IRQ,
122 }, 115 }, {
123 [3] = {
124 .start = UART2_MINT_RTS, 116 .start = UART2_MINT_RTS,
125 .end = UART2_MINT_RTS, 117 .end = UART2_MINT_RTS,
126 .flags = IORESOURCE_IRQ, 118 .flags = IORESOURCE_IRQ,
@@ -135,17 +127,15 @@ struct platform_device imx_uart2_device = {
135}; 127};
136 128
137static struct resource imx_rtc_resources[] = { 129static struct resource imx_rtc_resources[] = {
138 [0] = { 130 {
139 .start = 0x00204000, 131 .start = 0x00204000,
140 .end = 0x00204024, 132 .end = 0x00204024,
141 .flags = IORESOURCE_MEM, 133 .flags = IORESOURCE_MEM,
142 }, 134 }, {
143 [1] = {
144 .start = RTC_INT, 135 .start = RTC_INT,
145 .end = RTC_INT, 136 .end = RTC_INT,
146 .flags = IORESOURCE_IRQ, 137 .flags = IORESOURCE_IRQ,
147 }, 138 }, {
148 [2] = {
149 .start = RTC_SAMINT, 139 .start = RTC_SAMINT,
150 .end = RTC_SAMINT, 140 .end = RTC_SAMINT,
151 .flags = IORESOURCE_IRQ, 141 .flags = IORESOURCE_IRQ,
@@ -160,12 +150,11 @@ struct platform_device imx_rtc_device = {
160}; 150};
161 151
162static struct resource imx_wdt_resources[] = { 152static struct resource imx_wdt_resources[] = {
163 [0] = { 153 {
164 .start = 0x00201000, 154 .start = 0x00201000,
165 .end = 0x00201008, 155 .end = 0x00201008,
166 .flags = IORESOURCE_MEM, 156 .flags = IORESOURCE_MEM,
167 }, 157 }, {
168 [1] = {
169 .start = WDT_INT, 158 .start = WDT_INT,
170 .end = WDT_INT, 159 .end = WDT_INT,
171 .flags = IORESOURCE_IRQ, 160 .flags = IORESOURCE_IRQ,
@@ -180,42 +169,35 @@ struct platform_device imx_wdt_device = {
180}; 169};
181 170
182static struct resource imx_usb_resources[] = { 171static struct resource imx_usb_resources[] = {
183 [0] = { 172 {
184 .start = 0x00212000, 173 .start = 0x00212000,
185 .end = 0x00212148, 174 .end = 0x00212148,
186 .flags = IORESOURCE_MEM, 175 .flags = IORESOURCE_MEM,
187 }, 176 }, {
188 [1] = {
189 .start = USBD_INT0, 177 .start = USBD_INT0,
190 .end = USBD_INT0, 178 .end = USBD_INT0,
191 .flags = IORESOURCE_IRQ, 179 .flags = IORESOURCE_IRQ,
192 }, 180 }, {
193 [2] = {
194 .start = USBD_INT1, 181 .start = USBD_INT1,
195 .end = USBD_INT1, 182 .end = USBD_INT1,
196 .flags = IORESOURCE_IRQ, 183 .flags = IORESOURCE_IRQ,
197 }, 184 }, {
198 [3] = {
199 .start = USBD_INT2, 185 .start = USBD_INT2,
200 .end = USBD_INT2, 186 .end = USBD_INT2,
201 .flags = IORESOURCE_IRQ, 187 .flags = IORESOURCE_IRQ,
202 }, 188 }, {
203 [4] = {
204 .start = USBD_INT3, 189 .start = USBD_INT3,
205 .end = USBD_INT3, 190 .end = USBD_INT3,
206 .flags = IORESOURCE_IRQ, 191 .flags = IORESOURCE_IRQ,
207 }, 192 }, {
208 [5] = {
209 .start = USBD_INT4, 193 .start = USBD_INT4,
210 .end = USBD_INT4, 194 .end = USBD_INT4,
211 .flags = IORESOURCE_IRQ, 195 .flags = IORESOURCE_IRQ,
212 }, 196 }, {
213 [6] = {
214 .start = USBD_INT5, 197 .start = USBD_INT5,
215 .end = USBD_INT5, 198 .end = USBD_INT5,
216 .flags = IORESOURCE_IRQ, 199 .flags = IORESOURCE_IRQ,
217 }, 200 }, {
218 [7] = {
219 .start = USBD_INT6, 201 .start = USBD_INT6,
220 .end = USBD_INT6, 202 .end = USBD_INT6,
221 .flags = IORESOURCE_IRQ, 203 .flags = IORESOURCE_IRQ,
@@ -231,29 +213,26 @@ struct platform_device imx_usb_device = {
231 213
232/* GPIO port description */ 214/* GPIO port description */
233static struct mxc_gpio_port imx_gpio_ports[] = { 215static struct mxc_gpio_port imx_gpio_ports[] = {
234 [0] = { 216 {
235 .chip.label = "gpio-0", 217 .chip.label = "gpio-0",
236 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR), 218 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR),
237 .irq = GPIO_INT_PORTA, 219 .irq = GPIO_INT_PORTA,
238 .virtual_irq_start = MXC_GPIO_IRQ_START 220 .virtual_irq_start = MXC_GPIO_IRQ_START,
239 }, 221 }, {
240 [1] = {
241 .chip.label = "gpio-1", 222 .chip.label = "gpio-1",
242 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x100), 223 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
243 .irq = GPIO_INT_PORTB, 224 .irq = GPIO_INT_PORTB,
244 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 225 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
245 }, 226 }, {
246 [2] = {
247 .chip.label = "gpio-2", 227 .chip.label = "gpio-2",
248 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x200), 228 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
249 .irq = GPIO_INT_PORTC, 229 .irq = GPIO_INT_PORTC,
250 .virtual_irq_start = MXC_GPIO_IRQ_START + 64 230 .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
251 }, 231 }, {
252 [3] = {
253 .chip.label = "gpio-3", 232 .chip.label = "gpio-3",
254 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x300), 233 .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
255 .irq = GPIO_INT_PORTD, 234 .irq = GPIO_INT_PORTD,
256 .virtual_irq_start = MXC_GPIO_IRQ_START + 96 235 .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
257 } 236 }
258}; 237};
259 238
diff --git a/arch/arm/mach-mx1/generic.c b/arch/arm/mach-mx1/generic.c
index 7622c9b38c97..7f9fc1034c08 100644
--- a/arch/arm/mach-mx1/generic.c
+++ b/arch/arm/mach-mx1/generic.c
@@ -41,6 +41,13 @@ static struct map_desc imx_io_desc[] __initdata = {
41void __init mx1_map_io(void) 41void __init mx1_map_io(void)
42{ 42{
43 mxc_set_cpu_type(MXC_CPU_MX1); 43 mxc_set_cpu_type(MXC_CPU_MX1);
44 mxc_arch_reset_init(IO_ADDRESS(WDT_BASE_ADDR));
44 45
45 iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc)); 46 iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
46} 47}
48
49void __init mx1_init_irq(void)
50{
51 mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
52}
53
diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c
index e5b0c0a83c3b..30f04e56fafe 100644
--- a/arch/arm/mach-mx1/mx1ads.c
+++ b/arch/arm/mach-mx1/mx1ads.c
@@ -104,12 +104,10 @@ static struct imxi2c_platform_data mx1ads_i2c_data = {
104 104
105static struct i2c_board_info mx1ads_i2c_devices[] = { 105static struct i2c_board_info mx1ads_i2c_devices[] = {
106 { 106 {
107 I2C_BOARD_INFO("pcf857x", 0x22), 107 I2C_BOARD_INFO("pcf8575", 0x22),
108 .type = "pcf8575",
109 .platform_data = &pcf857x_data[0], 108 .platform_data = &pcf857x_data[0],
110 }, { 109 }, {
111 I2C_BOARD_INFO("pcf857x", 0x24), 110 I2C_BOARD_INFO("pcf8575", 0x24),
112 .type = "pcf8575",
113 .platform_data = &pcf857x_data[1], 111 .platform_data = &pcf857x_data[1],
114 }, 112 },
115}; 113};
@@ -151,7 +149,7 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS")
151 .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc, 149 .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
152 .boot_params = PHYS_OFFSET + 0x100, 150 .boot_params = PHYS_OFFSET + 0x100,
153 .map_io = mx1_map_io, 151 .map_io = mx1_map_io,
154 .init_irq = mxc_init_irq, 152 .init_irq = mx1_init_irq,
155 .timer = &mx1ads_timer, 153 .timer = &mx1ads_timer,
156 .init_machine = mx1ads_init, 154 .init_machine = mx1ads_init,
157MACHINE_END 155MACHINE_END
@@ -161,7 +159,7 @@ MACHINE_START(MXLADS, "Freescale MXLADS")
161 .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc, 159 .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
162 .boot_params = PHYS_OFFSET + 0x100, 160 .boot_params = PHYS_OFFSET + 0x100,
163 .map_io = mx1_map_io, 161 .map_io = mx1_map_io,
164 .init_irq = mxc_init_irq, 162 .init_irq = mx1_init_irq,
165 .timer = &mx1ads_timer, 163 .timer = &mx1ads_timer,
166 .init_machine = mx1ads_init, 164 .init_machine = mx1ads_init,
167MACHINE_END 165MACHINE_END
diff --git a/arch/arm/mach-mx1/scb9328.c b/arch/arm/mach-mx1/scb9328.c
index 20e0b5bcdffc..325d98df6053 100644
--- a/arch/arm/mach-mx1/scb9328.c
+++ b/arch/arm/mach-mx1/scb9328.c
@@ -68,22 +68,20 @@ static struct dm9000_plat_data dm9000_platdata = {
68 * to gain access to address latch registers and the data path. 68 * to gain access to address latch registers and the data path.
69 */ 69 */
70static struct resource dm9000x_resources[] = { 70static struct resource dm9000x_resources[] = {
71 [0] = { 71 {
72 .name = "address area", 72 .name = "address area",
73 .start = IMX_CS5_PHYS, 73 .start = IMX_CS5_PHYS,
74 .end = IMX_CS5_PHYS + 1, 74 .end = IMX_CS5_PHYS + 1,
75 .flags = IORESOURCE_MEM /* address access */ 75 .flags = IORESOURCE_MEM, /* address access */
76 }, 76 }, {
77 [1] = {
78 .name = "data area", 77 .name = "data area",
79 .start = IMX_CS5_PHYS + 4, 78 .start = IMX_CS5_PHYS + 4,
80 .end = IMX_CS5_PHYS + 5, 79 .end = IMX_CS5_PHYS + 5,
81 .flags = IORESOURCE_MEM /* data access */ 80 .flags = IORESOURCE_MEM, /* data access */
82 }, 81 }, {
83 [2] = {
84 .start = IRQ_GPIOC(3), 82 .start = IRQ_GPIOC(3),
85 .end = IRQ_GPIOC(3), 83 .end = IRQ_GPIOC(3),
86 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL 84 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
87 }, 85 },
88}; 86};
89 87
@@ -154,7 +152,7 @@ MACHINE_START(SCB9328, "Synertronixx scb9328")
154 .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, 152 .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
155 .boot_params = 0x08000100, 153 .boot_params = 0x08000100,
156 .map_io = mx1_map_io, 154 .map_io = mx1_map_io,
157 .init_irq = mxc_init_irq, 155 .init_irq = mx1_init_irq,
158 .timer = &scb9328_timer, 156 .timer = &scb9328_timer,
159 .init_machine = scb9328_init, 157 .init_machine = scb9328_init,
160MACHINE_END 158MACHINE_END
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig
index c77da586b71d..c8a2eac4d13c 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-mx2/Kconfig
@@ -53,6 +53,34 @@ config MACH_PCM970_BASEBOARD
53 53
54endchoice 54endchoice
55 55
56config MACH_EUKREA_CPUIMX27
57 bool "Eukrea CPUIMX27 module"
58 depends on MACH_MX27
59 help
60 Include support for Eukrea CPUIMX27 platform. This includes
61 specific configurations for the module and its peripherals.
62
63config MACH_EUKREA_CPUIMX27_USESDHC2
64 bool "CPUIMX27 integrates SDHC2 module"
65 depends on MACH_EUKREA_CPUIMX27
66 help
67 This adds support for the internal SDHC2 used on CPUIMX27 used
68 for wifi or eMMC.
69
70choice
71 prompt "Baseboard"
72 depends on MACH_EUKREA_CPUIMX27
73 default MACH_EUKREA_MBIMX27_BASEBOARD
74
75config MACH_EUKREA_MBIMX27_BASEBOARD
76 prompt "Eukrea MBIMX27 development board"
77 bool
78 help
79 This adds board specific devices that can be found on Eukrea's
80 MBIMX27 evaluation board.
81
82endchoice
83
56config MACH_MX27_3DS 84config MACH_MX27_3DS
57 bool "MX27PDK platform" 85 bool "MX27PDK platform"
58 depends on MACH_MX27 86 depends on MACH_MX27
@@ -67,4 +95,11 @@ config MACH_MX27LITE
67 Include support for MX27 LITEKIT platform. This includes specific 95 Include support for MX27 LITEKIT platform. This includes specific
68 configurations for the board and its peripherals. 96 configurations for the board and its peripherals.
69 97
98config MACH_PCA100
99 bool "Phytec phyCARD-s (pca100)"
100 depends on MACH_MX27
101 help
102 Include support for phyCARD-s (aka pca100) platform. This
103 includes specific configurations for the module and its peripherals.
104
70endif 105endif
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile
index b9b1cca4e9bc..19560f045632 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-mx2/Makefile
@@ -17,4 +17,7 @@ obj-$(CONFIG_MACH_PCM038) += pcm038.o
17obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o 17obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
18obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o 18obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o
19obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o 19obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o
20obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o
21obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
22obj-$(CONFIG_MACH_PCA100) += pca100.o
20 23
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c
index 0850fb88ec15..eede79855f4a 100644
--- a/arch/arm/mach-mx2/clock_imx21.c
+++ b/arch/arm/mach-mx2/clock_imx21.c
@@ -1004,6 +1004,6 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
1004 clk_enable(&uart_clk[0]); 1004 clk_enable(&uart_clk[0]);
1005#endif 1005#endif
1006 1006
1007 mxc_timer_init(&gpt_clk[0]); 1007 mxc_timer_init(&gpt_clk[0], IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
1008 return 0; 1008 return 0;
1009} 1009}
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index 2c971442f3f2..4089951acb47 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -643,7 +643,14 @@ static struct clk_lookup lookups[] = {
643 _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk) 643 _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
644 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) 644 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
645 _REGISTER_CLOCK(NULL, "csi", csi_clk) 645 _REGISTER_CLOCK(NULL, "csi", csi_clk)
646 _REGISTER_CLOCK(NULL, "usb", usb_clk) 646 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
647 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
648 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
649 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
650 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
651 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
652 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
653 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
647 _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk) 654 _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
648 _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk) 655 _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
649 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) 656 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
@@ -748,7 +755,7 @@ int __init mx27_clocks_init(unsigned long fref)
748 clk_enable(&uart1_clk); 755 clk_enable(&uart1_clk);
749#endif 756#endif
750 757
751 mxc_timer_init(&gpt1_clk); 758 mxc_timer_init(&gpt1_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
752 759
753 return 0; 760 return 0;
754} 761}
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c
index a0f1b3674327..50199aff0143 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-mx2/devices.c
@@ -40,45 +40,87 @@
40#include "devices.h" 40#include "devices.h"
41 41
42/* 42/*
43 * Resource definition for the MXC IrDA 43 * SPI master controller
44 *
45 * - i.MX1: 2 channel (slighly different register setting)
46 * - i.MX21: 2 channel
47 * - i.MX27: 3 channel
44 */ 48 */
45static struct resource mxc_irda_resources[] = { 49static struct resource mxc_spi_resources0[] = {
46 [0] = { 50 {
47 .start = UART3_BASE_ADDR, 51 .start = CSPI1_BASE_ADDR,
48 .end = UART3_BASE_ADDR + SZ_4K - 1, 52 .end = CSPI1_BASE_ADDR + SZ_4K - 1,
49 .flags = IORESOURCE_MEM, 53 .flags = IORESOURCE_MEM,
54 }, {
55 .start = MXC_INT_CSPI1,
56 .end = MXC_INT_CSPI1,
57 .flags = IORESOURCE_IRQ,
50 }, 58 },
51 [1] = { 59};
52 .start = MXC_INT_UART3, 60
53 .end = MXC_INT_UART3, 61static struct resource mxc_spi_resources1[] = {
54 .flags = IORESOURCE_IRQ, 62 {
63 .start = CSPI2_BASE_ADDR,
64 .end = CSPI2_BASE_ADDR + SZ_4K - 1,
65 .flags = IORESOURCE_MEM,
66 }, {
67 .start = MXC_INT_CSPI2,
68 .end = MXC_INT_CSPI2,
69 .flags = IORESOURCE_IRQ,
55 }, 70 },
56}; 71};
57 72
58/* Platform Data for MXC IrDA */ 73#ifdef CONFIG_MACH_MX27
59struct platform_device mxc_irda_device = { 74static struct resource mxc_spi_resources2[] = {
60 .name = "mxc_irda", 75 {
76 .start = CSPI3_BASE_ADDR,
77 .end = CSPI3_BASE_ADDR + SZ_4K - 1,
78 .flags = IORESOURCE_MEM,
79 }, {
80 .start = MXC_INT_CSPI3,
81 .end = MXC_INT_CSPI3,
82 .flags = IORESOURCE_IRQ,
83 },
84};
85#endif
86
87struct platform_device mxc_spi_device0 = {
88 .name = "spi_imx",
61 .id = 0, 89 .id = 0,
62 .num_resources = ARRAY_SIZE(mxc_irda_resources), 90 .num_resources = ARRAY_SIZE(mxc_spi_resources0),
63 .resource = mxc_irda_resources, 91 .resource = mxc_spi_resources0,
92};
93
94struct platform_device mxc_spi_device1 = {
95 .name = "spi_imx",
96 .id = 1,
97 .num_resources = ARRAY_SIZE(mxc_spi_resources1),
98 .resource = mxc_spi_resources1,
99};
100
101#ifdef CONFIG_MACH_MX27
102struct platform_device mxc_spi_device2 = {
103 .name = "spi_imx",
104 .id = 2,
105 .num_resources = ARRAY_SIZE(mxc_spi_resources2),
106 .resource = mxc_spi_resources2,
64}; 107};
108#endif
65 109
66/* 110/*
67 * General Purpose Timer 111 * General Purpose Timer
68 * - i.MX1: 2 timer (slighly different register handling) 112 * - i.MX21: 3 timers
69 * - i.MX21: 3 timer 113 * - i.MX27: 6 timers
70 * - i.MX27: 6 timer
71 */ 114 */
72 115
73/* We use gpt0 as system timer, so do not add a device for this one */ 116/* We use gpt0 as system timer, so do not add a device for this one */
74 117
75static struct resource timer1_resources[] = { 118static struct resource timer1_resources[] = {
76 [0] = { 119 {
77 .start = GPT2_BASE_ADDR, 120 .start = GPT2_BASE_ADDR,
78 .end = GPT2_BASE_ADDR + 0x17, 121 .end = GPT2_BASE_ADDR + 0x17,
79 .flags = IORESOURCE_MEM 122 .flags = IORESOURCE_MEM,
80 }, 123 }, {
81 [1] = {
82 .start = MXC_INT_GPT2, 124 .start = MXC_INT_GPT2,
83 .end = MXC_INT_GPT2, 125 .end = MXC_INT_GPT2,
84 .flags = IORESOURCE_IRQ, 126 .flags = IORESOURCE_IRQ,
@@ -89,16 +131,15 @@ struct platform_device mxc_gpt1 = {
89 .name = "imx_gpt", 131 .name = "imx_gpt",
90 .id = 1, 132 .id = 1,
91 .num_resources = ARRAY_SIZE(timer1_resources), 133 .num_resources = ARRAY_SIZE(timer1_resources),
92 .resource = timer1_resources 134 .resource = timer1_resources,
93}; 135};
94 136
95static struct resource timer2_resources[] = { 137static struct resource timer2_resources[] = {
96 [0] = { 138 {
97 .start = GPT3_BASE_ADDR, 139 .start = GPT3_BASE_ADDR,
98 .end = GPT3_BASE_ADDR + 0x17, 140 .end = GPT3_BASE_ADDR + 0x17,
99 .flags = IORESOURCE_MEM 141 .flags = IORESOURCE_MEM,
100 }, 142 }, {
101 [1] = {
102 .start = MXC_INT_GPT3, 143 .start = MXC_INT_GPT3,
103 .end = MXC_INT_GPT3, 144 .end = MXC_INT_GPT3,
104 .flags = IORESOURCE_IRQ, 145 .flags = IORESOURCE_IRQ,
@@ -109,17 +150,16 @@ struct platform_device mxc_gpt2 = {
109 .name = "imx_gpt", 150 .name = "imx_gpt",
110 .id = 2, 151 .id = 2,
111 .num_resources = ARRAY_SIZE(timer2_resources), 152 .num_resources = ARRAY_SIZE(timer2_resources),
112 .resource = timer2_resources 153 .resource = timer2_resources,
113}; 154};
114 155
115#ifdef CONFIG_MACH_MX27 156#ifdef CONFIG_MACH_MX27
116static struct resource timer3_resources[] = { 157static struct resource timer3_resources[] = {
117 [0] = { 158 {
118 .start = GPT4_BASE_ADDR, 159 .start = GPT4_BASE_ADDR,
119 .end = GPT4_BASE_ADDR + 0x17, 160 .end = GPT4_BASE_ADDR + 0x17,
120 .flags = IORESOURCE_MEM 161 .flags = IORESOURCE_MEM,
121 }, 162 }, {
122 [1] = {
123 .start = MXC_INT_GPT4, 163 .start = MXC_INT_GPT4,
124 .end = MXC_INT_GPT4, 164 .end = MXC_INT_GPT4,
125 .flags = IORESOURCE_IRQ, 165 .flags = IORESOURCE_IRQ,
@@ -130,16 +170,15 @@ struct platform_device mxc_gpt3 = {
130 .name = "imx_gpt", 170 .name = "imx_gpt",
131 .id = 3, 171 .id = 3,
132 .num_resources = ARRAY_SIZE(timer3_resources), 172 .num_resources = ARRAY_SIZE(timer3_resources),
133 .resource = timer3_resources 173 .resource = timer3_resources,
134}; 174};
135 175
136static struct resource timer4_resources[] = { 176static struct resource timer4_resources[] = {
137 [0] = { 177 {
138 .start = GPT5_BASE_ADDR, 178 .start = GPT5_BASE_ADDR,
139 .end = GPT5_BASE_ADDR + 0x17, 179 .end = GPT5_BASE_ADDR + 0x17,
140 .flags = IORESOURCE_MEM 180 .flags = IORESOURCE_MEM,
141 }, 181 }, {
142 [1] = {
143 .start = MXC_INT_GPT5, 182 .start = MXC_INT_GPT5,
144 .end = MXC_INT_GPT5, 183 .end = MXC_INT_GPT5,
145 .flags = IORESOURCE_IRQ, 184 .flags = IORESOURCE_IRQ,
@@ -150,16 +189,15 @@ struct platform_device mxc_gpt4 = {
150 .name = "imx_gpt", 189 .name = "imx_gpt",
151 .id = 4, 190 .id = 4,
152 .num_resources = ARRAY_SIZE(timer4_resources), 191 .num_resources = ARRAY_SIZE(timer4_resources),
153 .resource = timer4_resources 192 .resource = timer4_resources,
154}; 193};
155 194
156static struct resource timer5_resources[] = { 195static struct resource timer5_resources[] = {
157 [0] = { 196 {
158 .start = GPT6_BASE_ADDR, 197 .start = GPT6_BASE_ADDR,
159 .end = GPT6_BASE_ADDR + 0x17, 198 .end = GPT6_BASE_ADDR + 0x17,
160 .flags = IORESOURCE_MEM 199 .flags = IORESOURCE_MEM,
161 }, 200 }, {
162 [1] = {
163 .start = MXC_INT_GPT6, 201 .start = MXC_INT_GPT6,
164 .end = MXC_INT_GPT6, 202 .end = MXC_INT_GPT6,
165 .flags = IORESOURCE_IRQ, 203 .flags = IORESOURCE_IRQ,
@@ -170,7 +208,7 @@ struct platform_device mxc_gpt5 = {
170 .name = "imx_gpt", 208 .name = "imx_gpt",
171 .id = 5, 209 .id = 5,
172 .num_resources = ARRAY_SIZE(timer5_resources), 210 .num_resources = ARRAY_SIZE(timer5_resources),
173 .resource = timer5_resources 211 .resource = timer5_resources,
174}; 212};
175#endif 213#endif
176 214
@@ -214,11 +252,11 @@ static struct resource mxc_nand_resources[] = {
214 { 252 {
215 .start = NFC_BASE_ADDR, 253 .start = NFC_BASE_ADDR,
216 .end = NFC_BASE_ADDR + 0xfff, 254 .end = NFC_BASE_ADDR + 0xfff,
217 .flags = IORESOURCE_MEM 255 .flags = IORESOURCE_MEM,
218 }, { 256 }, {
219 .start = MXC_INT_NANDFC, 257 .start = MXC_INT_NANDFC,
220 .end = MXC_INT_NANDFC, 258 .end = MXC_INT_NANDFC,
221 .flags = IORESOURCE_IRQ 259 .flags = IORESOURCE_IRQ,
222 }, 260 },
223}; 261};
224 262
@@ -240,8 +278,7 @@ static struct resource mxc_fb[] = {
240 .start = LCDC_BASE_ADDR, 278 .start = LCDC_BASE_ADDR,
241 .end = LCDC_BASE_ADDR + 0xFFF, 279 .end = LCDC_BASE_ADDR + 0xFFF,
242 .flags = IORESOURCE_MEM, 280 .flags = IORESOURCE_MEM,
243 }, 281 }, {
244 {
245 .start = MXC_INT_LCDC, 282 .start = MXC_INT_LCDC,
246 .end = MXC_INT_LCDC, 283 .end = MXC_INT_LCDC,
247 .flags = IORESOURCE_IRQ, 284 .flags = IORESOURCE_IRQ,
@@ -264,11 +301,11 @@ static struct resource mxc_fec_resources[] = {
264 { 301 {
265 .start = FEC_BASE_ADDR, 302 .start = FEC_BASE_ADDR,
266 .end = FEC_BASE_ADDR + 0xfff, 303 .end = FEC_BASE_ADDR + 0xfff,
267 .flags = IORESOURCE_MEM 304 .flags = IORESOURCE_MEM,
268 }, { 305 }, {
269 .start = MXC_INT_FEC, 306 .start = MXC_INT_FEC,
270 .end = MXC_INT_FEC, 307 .end = MXC_INT_FEC,
271 .flags = IORESOURCE_IRQ 308 .flags = IORESOURCE_IRQ,
272 }, 309 },
273}; 310};
274 311
@@ -281,15 +318,14 @@ struct platform_device mxc_fec_device = {
281#endif 318#endif
282 319
283static struct resource mxc_i2c_1_resources[] = { 320static struct resource mxc_i2c_1_resources[] = {
284 [0] = { 321 {
285 .start = I2C_BASE_ADDR, 322 .start = I2C_BASE_ADDR,
286 .end = I2C_BASE_ADDR + 0x0fff, 323 .end = I2C_BASE_ADDR + 0x0fff,
287 .flags = IORESOURCE_MEM 324 .flags = IORESOURCE_MEM,
288 }, 325 }, {
289 [1] = {
290 .start = MXC_INT_I2C, 326 .start = MXC_INT_I2C,
291 .end = MXC_INT_I2C, 327 .end = MXC_INT_I2C,
292 .flags = IORESOURCE_IRQ 328 .flags = IORESOURCE_IRQ,
293 } 329 }
294}; 330};
295 331
@@ -297,20 +333,19 @@ struct platform_device mxc_i2c_device0 = {
297 .name = "imx-i2c", 333 .name = "imx-i2c",
298 .id = 0, 334 .id = 0,
299 .num_resources = ARRAY_SIZE(mxc_i2c_1_resources), 335 .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
300 .resource = mxc_i2c_1_resources 336 .resource = mxc_i2c_1_resources,
301}; 337};
302 338
303#ifdef CONFIG_MACH_MX27 339#ifdef CONFIG_MACH_MX27
304static struct resource mxc_i2c_2_resources[] = { 340static struct resource mxc_i2c_2_resources[] = {
305 [0] = { 341 {
306 .start = I2C2_BASE_ADDR, 342 .start = I2C2_BASE_ADDR,
307 .end = I2C2_BASE_ADDR + 0x0fff, 343 .end = I2C2_BASE_ADDR + 0x0fff,
308 .flags = IORESOURCE_MEM 344 .flags = IORESOURCE_MEM,
309 }, 345 }, {
310 [1] = {
311 .start = MXC_INT_I2C2, 346 .start = MXC_INT_I2C2,
312 .end = MXC_INT_I2C2, 347 .end = MXC_INT_I2C2,
313 .flags = IORESOURCE_IRQ 348 .flags = IORESOURCE_IRQ,
314 } 349 }
315}; 350};
316 351
@@ -318,17 +353,16 @@ struct platform_device mxc_i2c_device1 = {
318 .name = "imx-i2c", 353 .name = "imx-i2c",
319 .id = 1, 354 .id = 1,
320 .num_resources = ARRAY_SIZE(mxc_i2c_2_resources), 355 .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
321 .resource = mxc_i2c_2_resources 356 .resource = mxc_i2c_2_resources,
322}; 357};
323#endif 358#endif
324 359
325static struct resource mxc_pwm_resources[] = { 360static struct resource mxc_pwm_resources[] = {
326 [0] = { 361 {
327 .start = PWM_BASE_ADDR, 362 .start = PWM_BASE_ADDR,
328 .end = PWM_BASE_ADDR + 0x0fff, 363 .end = PWM_BASE_ADDR + 0x0fff,
329 .flags = IORESOURCE_MEM 364 .flags = IORESOURCE_MEM,
330 }, 365 }, {
331 [1] = {
332 .start = MXC_INT_PWM, 366 .start = MXC_INT_PWM,
333 .end = MXC_INT_PWM, 367 .end = MXC_INT_PWM,
334 .flags = IORESOURCE_IRQ, 368 .flags = IORESOURCE_IRQ,
@@ -339,28 +373,26 @@ struct platform_device mxc_pwm_device = {
339 .name = "mxc_pwm", 373 .name = "mxc_pwm",
340 .id = 0, 374 .id = 0,
341 .num_resources = ARRAY_SIZE(mxc_pwm_resources), 375 .num_resources = ARRAY_SIZE(mxc_pwm_resources),
342 .resource = mxc_pwm_resources 376 .resource = mxc_pwm_resources,
343}; 377};
344 378
345/* 379/*
346 * Resource definition for the MXC SDHC 380 * Resource definition for the MXC SDHC
347 */ 381 */
348static struct resource mxc_sdhc1_resources[] = { 382static struct resource mxc_sdhc1_resources[] = {
349 [0] = { 383 {
350 .start = SDHC1_BASE_ADDR, 384 .start = SDHC1_BASE_ADDR,
351 .end = SDHC1_BASE_ADDR + SZ_4K - 1, 385 .end = SDHC1_BASE_ADDR + SZ_4K - 1,
352 .flags = IORESOURCE_MEM, 386 .flags = IORESOURCE_MEM,
353 }, 387 }, {
354 [1] = { 388 .start = MXC_INT_SDHC1,
355 .start = MXC_INT_SDHC1, 389 .end = MXC_INT_SDHC1,
356 .end = MXC_INT_SDHC1, 390 .flags = IORESOURCE_IRQ,
357 .flags = IORESOURCE_IRQ, 391 }, {
358 }, 392 .start = DMA_REQ_SDHC1,
359 [2] = { 393 .end = DMA_REQ_SDHC1,
360 .start = DMA_REQ_SDHC1, 394 .flags = IORESOURCE_DMA,
361 .end = DMA_REQ_SDHC1, 395 },
362 .flags = IORESOURCE_DMA
363 },
364}; 396};
365 397
366static u64 mxc_sdhc1_dmamask = 0xffffffffUL; 398static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
@@ -377,21 +409,19 @@ struct platform_device mxc_sdhc_device0 = {
377}; 409};
378 410
379static struct resource mxc_sdhc2_resources[] = { 411static struct resource mxc_sdhc2_resources[] = {
380 [0] = { 412 {
381 .start = SDHC2_BASE_ADDR, 413 .start = SDHC2_BASE_ADDR,
382 .end = SDHC2_BASE_ADDR + SZ_4K - 1, 414 .end = SDHC2_BASE_ADDR + SZ_4K - 1,
383 .flags = IORESOURCE_MEM, 415 .flags = IORESOURCE_MEM,
384 }, 416 }, {
385 [1] = { 417 .start = MXC_INT_SDHC2,
386 .start = MXC_INT_SDHC2, 418 .end = MXC_INT_SDHC2,
387 .end = MXC_INT_SDHC2, 419 .flags = IORESOURCE_IRQ,
388 .flags = IORESOURCE_IRQ, 420 }, {
389 }, 421 .start = DMA_REQ_SDHC2,
390 [2] = { 422 .end = DMA_REQ_SDHC2,
391 .start = DMA_REQ_SDHC2, 423 .flags = IORESOURCE_DMA,
392 .end = DMA_REQ_SDHC2, 424 },
393 .flags = IORESOURCE_DMA
394 },
395}; 425};
396 426
397static u64 mxc_sdhc2_dmamask = 0xffffffffUL; 427static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
@@ -407,35 +437,123 @@ struct platform_device mxc_sdhc_device1 = {
407 .resource = mxc_sdhc2_resources, 437 .resource = mxc_sdhc2_resources,
408}; 438};
409 439
440#ifdef CONFIG_MACH_MX27
441static struct resource otg_resources[] = {
442 {
443 .start = OTG_BASE_ADDR,
444 .end = OTG_BASE_ADDR + 0x1ff,
445 .flags = IORESOURCE_MEM,
446 }, {
447 .start = MXC_INT_USB3,
448 .end = MXC_INT_USB3,
449 .flags = IORESOURCE_IRQ,
450 },
451};
452
453static u64 otg_dmamask = 0xffffffffUL;
454
455/* OTG gadget device */
456struct platform_device mxc_otg_udc_device = {
457 .name = "fsl-usb2-udc",
458 .id = -1,
459 .dev = {
460 .dma_mask = &otg_dmamask,
461 .coherent_dma_mask = 0xffffffffUL,
462 },
463 .resource = otg_resources,
464 .num_resources = ARRAY_SIZE(otg_resources),
465};
466
467/* OTG host */
468struct platform_device mxc_otg_host = {
469 .name = "mxc-ehci",
470 .id = 0,
471 .dev = {
472 .coherent_dma_mask = 0xffffffff,
473 .dma_mask = &otg_dmamask,
474 },
475 .resource = otg_resources,
476 .num_resources = ARRAY_SIZE(otg_resources),
477};
478
479/* USB host 1 */
480
481static u64 usbh1_dmamask = 0xffffffffUL;
482
483static struct resource mxc_usbh1_resources[] = {
484 {
485 .start = OTG_BASE_ADDR + 0x200,
486 .end = OTG_BASE_ADDR + 0x3ff,
487 .flags = IORESOURCE_MEM,
488 }, {
489 .start = MXC_INT_USB1,
490 .end = MXC_INT_USB1,
491 .flags = IORESOURCE_IRQ,
492 },
493};
494
495struct platform_device mxc_usbh1 = {
496 .name = "mxc-ehci",
497 .id = 1,
498 .dev = {
499 .coherent_dma_mask = 0xffffffff,
500 .dma_mask = &usbh1_dmamask,
501 },
502 .resource = mxc_usbh1_resources,
503 .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
504};
505
506/* USB host 2 */
507static u64 usbh2_dmamask = 0xffffffffUL;
508
509static struct resource mxc_usbh2_resources[] = {
510 {
511 .start = OTG_BASE_ADDR + 0x400,
512 .end = OTG_BASE_ADDR + 0x5ff,
513 .flags = IORESOURCE_MEM,
514 }, {
515 .start = MXC_INT_USB2,
516 .end = MXC_INT_USB2,
517 .flags = IORESOURCE_IRQ,
518 },
519};
520
521struct platform_device mxc_usbh2 = {
522 .name = "mxc-ehci",
523 .id = 2,
524 .dev = {
525 .coherent_dma_mask = 0xffffffff,
526 .dma_mask = &usbh2_dmamask,
527 },
528 .resource = mxc_usbh2_resources,
529 .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
530};
531#endif
532
410/* GPIO port description */ 533/* GPIO port description */
411static struct mxc_gpio_port imx_gpio_ports[] = { 534static struct mxc_gpio_port imx_gpio_ports[] = {
412 [0] = { 535 {
413 .chip.label = "gpio-0", 536 .chip.label = "gpio-0",
414 .irq = MXC_INT_GPIO, 537 .irq = MXC_INT_GPIO,
415 .base = IO_ADDRESS(GPIO_BASE_ADDR), 538 .base = IO_ADDRESS(GPIO_BASE_ADDR),
416 .virtual_irq_start = MXC_GPIO_IRQ_START, 539 .virtual_irq_start = MXC_GPIO_IRQ_START,
417 }, 540 }, {
418 [1] = {
419 .chip.label = "gpio-1", 541 .chip.label = "gpio-1",
420 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100), 542 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
421 .virtual_irq_start = MXC_GPIO_IRQ_START + 32, 543 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
422 }, 544 }, {
423 [2] = {
424 .chip.label = "gpio-2", 545 .chip.label = "gpio-2",
425 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200), 546 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
426 .virtual_irq_start = MXC_GPIO_IRQ_START + 64, 547 .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
427 }, 548 }, {
428 [3] = {
429 .chip.label = "gpio-3", 549 .chip.label = "gpio-3",
430 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300), 550 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
431 .virtual_irq_start = MXC_GPIO_IRQ_START + 96, 551 .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
432 }, 552 }, {
433 [4] = {
434 .chip.label = "gpio-4", 553 .chip.label = "gpio-4",
435 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400), 554 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
436 .virtual_irq_start = MXC_GPIO_IRQ_START + 128, 555 .virtual_irq_start = MXC_GPIO_IRQ_START + 128,
437 }, 556 }, {
438 [5] = {
439 .chip.label = "gpio-5", 557 .chip.label = "gpio-5",
440 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500), 558 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
441 .virtual_irq_start = MXC_GPIO_IRQ_START + 160, 559 .virtual_irq_start = MXC_GPIO_IRQ_START + 160,
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h
index 049005bb6aa9..d315406d6725 100644
--- a/arch/arm/mach-mx2/devices.h
+++ b/arch/arm/mach-mx2/devices.h
@@ -4,7 +4,6 @@ extern struct platform_device mxc_gpt3;
4extern struct platform_device mxc_gpt4; 4extern struct platform_device mxc_gpt4;
5extern struct platform_device mxc_gpt5; 5extern struct platform_device mxc_gpt5;
6extern struct platform_device mxc_wdt; 6extern struct platform_device mxc_wdt;
7extern struct platform_device mxc_irda_device;
8extern struct platform_device mxc_uart_device0; 7extern struct platform_device mxc_uart_device0;
9extern struct platform_device mxc_uart_device1; 8extern struct platform_device mxc_uart_device1;
10extern struct platform_device mxc_uart_device2; 9extern struct platform_device mxc_uart_device2;
@@ -20,3 +19,11 @@ extern struct platform_device mxc_i2c_device0;
20extern struct platform_device mxc_i2c_device1; 19extern struct platform_device mxc_i2c_device1;
21extern struct platform_device mxc_sdhc_device0; 20extern struct platform_device mxc_sdhc_device0;
22extern struct platform_device mxc_sdhc_device1; 21extern struct platform_device mxc_sdhc_device1;
22extern struct platform_device mxc_otg_udc_device;
23extern struct platform_device mxc_otg_host;
24extern struct platform_device mxc_usbh1;
25extern struct platform_device mxc_usbh2;
26extern struct platform_device mxc_spi_device0;
27extern struct platform_device mxc_spi_device1;
28extern struct platform_device mxc_spi_device2;
29
diff --git a/arch/arm/mach-mx2/eukrea_cpuimx27.c b/arch/arm/mach-mx2/eukrea_cpuimx27.c
new file mode 100644
index 000000000000..7b187606682c
--- /dev/null
+++ b/arch/arm/mach-mx2/eukrea_cpuimx27.c
@@ -0,0 +1,234 @@
1/*
2 * Copyright (C) 2009 Eric Benard - eric@eukrea.com
3 *
4 * Based on pcm038.c which is :
5 * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
6 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
21 */
22
23#include <linux/i2c.h>
24#include <linux/io.h>
25#include <linux/mtd/plat-ram.h>
26#include <linux/mtd/physmap.h>
27#include <linux/platform_device.h>
28#include <linux/serial_8250.h>
29
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/time.h>
33#include <asm/mach/map.h>
34
35#include <mach/board-eukrea_cpuimx27.h>
36#include <mach/common.h>
37#include <mach/hardware.h>
38#include <mach/i2c.h>
39#include <mach/iomux.h>
40#include <mach/imx-uart.h>
41#include <mach/mxc_nand.h>
42
43#include "devices.h"
44
45static int eukrea_cpuimx27_pins[] = {
46 /* UART1 */
47 PE12_PF_UART1_TXD,
48 PE13_PF_UART1_RXD,
49 PE14_PF_UART1_CTS,
50 PE15_PF_UART1_RTS,
51 /* UART4 */
52 PB26_AF_UART4_RTS,
53 PB28_AF_UART4_TXD,
54 PB29_AF_UART4_CTS,
55 PB31_AF_UART4_RXD,
56 /* FEC */
57 PD0_AIN_FEC_TXD0,
58 PD1_AIN_FEC_TXD1,
59 PD2_AIN_FEC_TXD2,
60 PD3_AIN_FEC_TXD3,
61 PD4_AOUT_FEC_RX_ER,
62 PD5_AOUT_FEC_RXD1,
63 PD6_AOUT_FEC_RXD2,
64 PD7_AOUT_FEC_RXD3,
65 PD8_AF_FEC_MDIO,
66 PD9_AIN_FEC_MDC,
67 PD10_AOUT_FEC_CRS,
68 PD11_AOUT_FEC_TX_CLK,
69 PD12_AOUT_FEC_RXD0,
70 PD13_AOUT_FEC_RX_DV,
71 PD14_AOUT_FEC_RX_CLK,
72 PD15_AOUT_FEC_COL,
73 PD16_AIN_FEC_TX_ER,
74 PF23_AIN_FEC_TX_EN,
75 /* I2C1 */
76 PD17_PF_I2C_DATA,
77 PD18_PF_I2C_CLK,
78 /* SDHC2 */
79 PB4_PF_SD2_D0,
80 PB5_PF_SD2_D1,
81 PB6_PF_SD2_D2,
82 PB7_PF_SD2_D3,
83 PB8_PF_SD2_CMD,
84 PB9_PF_SD2_CLK,
85#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
86 /* Quad UART's IRQ */
87 GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN,
88 GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN,
89 GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN,
90 GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN,
91#endif
92};
93
94static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
95 .width = 2,
96};
97
98static struct resource eukrea_cpuimx27_flash_resource = {
99 .start = 0xc0000000,
100 .end = 0xc3ffffff,
101 .flags = IORESOURCE_MEM,
102};
103
104static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
105 .name = "physmap-flash",
106 .id = 0,
107 .dev = {
108 .platform_data = &eukrea_cpuimx27_flash_data,
109 },
110 .num_resources = 1,
111 .resource = &eukrea_cpuimx27_flash_resource,
112};
113
114static struct imxuart_platform_data uart_pdata[] = {
115 {
116 .flags = IMXUART_HAVE_RTSCTS,
117 }, {
118 .flags = IMXUART_HAVE_RTSCTS,
119 },
120};
121
122static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
123 .width = 1,
124 .hw_ecc = 1,
125};
126
127static struct platform_device *platform_devices[] __initdata = {
128 &eukrea_cpuimx27_nor_mtd_device,
129 &mxc_fec_device,
130};
131
132static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
133 .bitrate = 100000,
134};
135
136static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
137 {
138 I2C_BOARD_INFO("pcf8563", 0x51),
139 },
140};
141
142#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
143static struct plat_serial8250_port serial_platform_data[] = {
144 {
145 .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x200000),
146 .irq = IRQ_GPIOB(23),
147 .uartclk = 14745600,
148 .regshift = 1,
149 .iotype = UPIO_MEM,
150 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
151 }, {
152 .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x400000),
153 .irq = IRQ_GPIOB(22),
154 .uartclk = 14745600,
155 .regshift = 1,
156 .iotype = UPIO_MEM,
157 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
158 }, {
159 .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x800000),
160 .irq = IRQ_GPIOB(27),
161 .uartclk = 14745600,
162 .regshift = 1,
163 .iotype = UPIO_MEM,
164 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
165 }, {
166 .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x1000000),
167 .irq = IRQ_GPIOB(30),
168 .uartclk = 14745600,
169 .regshift = 1,
170 .iotype = UPIO_MEM,
171 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
172 }, {
173 }
174};
175
176static struct platform_device serial_device = {
177 .name = "serial8250",
178 .id = 0,
179 .dev = {
180 .platform_data = serial_platform_data,
181 },
182};
183#endif
184
185static void __init eukrea_cpuimx27_init(void)
186{
187 mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
188 ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
189
190 mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
191
192 mxc_register_device(&mxc_nand_device, &eukrea_cpuimx27_nand_board_info);
193
194 i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
195 ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
196
197 mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data);
198
199 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
200
201#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
202 /* SDHC2 can be used for Wifi */
203 mxc_register_device(&mxc_sdhc_device1, NULL);
204 /* in which case UART4 is also used for Bluetooth */
205 mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
206#endif
207
208#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
209 platform_device_register(&serial_device);
210#endif
211
212#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
213 eukrea_mbimx27_baseboard_init();
214#endif
215}
216
217static void __init eukrea_cpuimx27_timer_init(void)
218{
219 mx27_clocks_init(26000000);
220}
221
222static struct sys_timer eukrea_cpuimx27_timer = {
223 .init = eukrea_cpuimx27_timer_init,
224};
225
226MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
227 .phys_io = AIPI_BASE_ADDR,
228 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
229 .boot_params = PHYS_OFFSET + 0x100,
230 .map_io = mx27_map_io,
231 .init_irq = mx27_init_irq,
232 .init_machine = eukrea_cpuimx27_init,
233 .timer = &eukrea_cpuimx27_timer,
234MACHINE_END
diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
new file mode 100644
index 000000000000..7382b6d27ee1
--- /dev/null
+++ b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
@@ -0,0 +1,249 @@
1/*
2 * Copyright (C) 2009 Eric Benard - eric@eukrea.com
3 *
4 * Based on pcm970-baseboard.c which is :
5 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22#include <linux/gpio.h>
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25#include <linux/spi/spi.h>
26#include <linux/spi/ads7846.h>
27
28#include <asm/mach/arch.h>
29
30#include <mach/common.h>
31#include <mach/iomux.h>
32#include <mach/imxfb.h>
33#include <mach/hardware.h>
34#include <mach/mmc.h>
35#include <mach/imx-uart.h>
36
37#include "devices.h"
38
39static int eukrea_mbimx27_pins[] = {
40 /* UART2 */
41 PE3_PF_UART2_CTS,
42 PE4_PF_UART2_RTS,
43 PE6_PF_UART2_TXD,
44 PE7_PF_UART2_RXD,
45 /* UART3 */
46 PE8_PF_UART3_TXD,
47 PE9_PF_UART3_RXD,
48 PE10_PF_UART3_CTS,
49 PE11_PF_UART3_RTS,
50 /* UART4 */
51 PB26_AF_UART4_RTS,
52 PB28_AF_UART4_TXD,
53 PB29_AF_UART4_CTS,
54 PB31_AF_UART4_RXD,
55 /* SDHC1*/
56 PE18_PF_SD1_D0,
57 PE19_PF_SD1_D1,
58 PE20_PF_SD1_D2,
59 PE21_PF_SD1_D3,
60 PE22_PF_SD1_CMD,
61 PE23_PF_SD1_CLK,
62 /* display */
63 PA5_PF_LSCLK,
64 PA6_PF_LD0,
65 PA7_PF_LD1,
66 PA8_PF_LD2,
67 PA9_PF_LD3,
68 PA10_PF_LD4,
69 PA11_PF_LD5,
70 PA12_PF_LD6,
71 PA13_PF_LD7,
72 PA14_PF_LD8,
73 PA15_PF_LD9,
74 PA16_PF_LD10,
75 PA17_PF_LD11,
76 PA18_PF_LD12,
77 PA19_PF_LD13,
78 PA20_PF_LD14,
79 PA21_PF_LD15,
80 PA22_PF_LD16,
81 PA23_PF_LD17,
82 PA28_PF_HSYNC,
83 PA29_PF_VSYNC,
84 PA30_PF_CONTRAST,
85 PA31_PF_OE_ACD,
86 /* SPI1 */
87 PD28_PF_CSPI1_SS0,
88 PD29_PF_CSPI1_SCLK,
89 PD30_PF_CSPI1_MISO,
90 PD31_PF_CSPI1_MOSI,
91};
92
93static struct gpio_led gpio_leds[] = {
94 {
95 .name = "led1",
96 .default_trigger = "heartbeat",
97 .active_low = 1,
98 .gpio = GPIO_PORTF | 16,
99 },
100 {
101 .name = "led2",
102 .default_trigger = "none",
103 .active_low = 1,
104 .gpio = GPIO_PORTF | 19,
105 },
106 {
107 .name = "backlight",
108 .default_trigger = "backlight",
109 .active_low = 0,
110 .gpio = GPIO_PORTE | 5,
111 },
112};
113
114static struct gpio_led_platform_data gpio_led_info = {
115 .leds = gpio_leds,
116 .num_leds = ARRAY_SIZE(gpio_leds),
117};
118
119static struct platform_device leds_gpio = {
120 .name = "leds-gpio",
121 .id = -1,
122 .dev = {
123 .platform_data = &gpio_led_info,
124 },
125};
126
127static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
128 {
129 .mode = {
130 .name = "CMO-QGVA",
131 .refresh = 60,
132 .xres = 320,
133 .yres = 240,
134 .pixclock = 156000,
135 .hsync_len = 30,
136 .left_margin = 38,
137 .right_margin = 20,
138 .vsync_len = 3,
139 .upper_margin = 15,
140 .lower_margin = 4,
141 },
142 .pcr = 0xFAD08B80,
143 .bpp = 16,
144 },
145};
146
147static struct imx_fb_platform_data eukrea_mbimx27_fb_data = {
148 .mode = eukrea_mbimx27_modes,
149 .num_modes = ARRAY_SIZE(eukrea_mbimx27_modes),
150
151 .pwmr = 0x00A903FF,
152 .lscr1 = 0x00120300,
153 .dmacr = 0x00040060,
154};
155
156static struct imxuart_platform_data uart_pdata[] = {
157 {
158 .flags = IMXUART_HAVE_RTSCTS,
159 },
160 {
161 .flags = IMXUART_HAVE_RTSCTS,
162 },
163};
164
165#if defined(CONFIG_TOUCHSCREEN_ADS7846)
166 || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
167
168#define ADS7846_PENDOWN (GPIO_PORTD | 25)
169
170static void ads7846_dev_init(void)
171{
172 if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) {
173 printk(KERN_ERR "can't get ads746 pen down GPIO\n");
174 return;
175 }
176
177 gpio_direction_input(ADS7846_PENDOWN);
178}
179
180static int ads7846_get_pendown_state(void)
181{
182 return !gpio_get_value(ADS7846_PENDOWN);
183}
184
185static struct ads7846_platform_data ads7846_config __initdata = {
186 .get_pendown_state = ads7846_get_pendown_state,
187 .keep_vref_on = 1,
188};
189
190static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
191 [0] = {
192 .modalias = "ads7846",
193 .bus_num = 0,
194 .chip_select = 0,
195 .max_speed_hz = 1500000,
196 .irq = IRQ_GPIOD(25),
197 .platform_data = &ads7846_config,
198 .mode = SPI_MODE_2,
199 },
200};
201
202static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28};
203
204static struct spi_imx_master eukrea_mbimx27_spi_0_data = {
205 .chipselect = eukrea_mbimx27_spi_cs,
206 .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
207};
208#endif
209
210static struct platform_device *platform_devices[] __initdata = {
211 &leds_gpio,
212};
213
214/*
215 * system init for baseboard usage. Will be called by cpuimx27 init.
216 *
217 * Add platform devices present on this baseboard and init
218 * them from CPU side as far as required to use them later on
219 */
220void __init eukrea_mbimx27_baseboard_init(void)
221{
222 mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
223 ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
224
225 mxc_register_device(&mxc_uart_device1, &uart_pdata[0]);
226 mxc_register_device(&mxc_uart_device2, &uart_pdata[1]);
227
228 mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data);
229 mxc_register_device(&mxc_sdhc_device0, NULL);
230
231#if defined(CONFIG_TOUCHSCREEN_ADS7846)
232 || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
233 /* SPI and ADS7846 Touchscreen controler init */
234 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
235 mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN);
236 mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data);
237 spi_register_board_info(eukrea_mbimx27_spi_board_info,
238 ARRAY_SIZE(eukrea_mbimx27_spi_board_info));
239 ads7846_dev_init();
240#endif
241
242 /* Leds configuration */
243 mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT);
244 mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT);
245 /* Backlight */
246 mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT);
247
248 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
249}
diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c
index 169372f69d8f..ae8f759134d1 100644
--- a/arch/arm/mach-mx2/generic.c
+++ b/arch/arm/mach-mx2/generic.c
@@ -72,6 +72,7 @@ static struct map_desc mxc_io_desc[] __initdata = {
72void __init mx21_map_io(void) 72void __init mx21_map_io(void)
73{ 73{
74 mxc_set_cpu_type(MXC_CPU_MX21); 74 mxc_set_cpu_type(MXC_CPU_MX21);
75 mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
75 76
76 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); 77 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
77} 78}
@@ -79,7 +80,18 @@ void __init mx21_map_io(void)
79void __init mx27_map_io(void) 80void __init mx27_map_io(void)
80{ 81{
81 mxc_set_cpu_type(MXC_CPU_MX27); 82 mxc_set_cpu_type(MXC_CPU_MX27);
83 mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
82 84
83 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); 85 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
84} 86}
85 87
88void __init mx27_init_irq(void)
89{
90 mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
91}
92
93void __init mx21_init_irq(void)
94{
95 mx27_init_irq();
96}
97
diff --git a/arch/arm/mach-mx2/mx21ads.c b/arch/arm/mach-mx2/mx21ads.c
index a5ee461cb405..cf5f77cbc2f1 100644
--- a/arch/arm/mach-mx2/mx21ads.c
+++ b/arch/arm/mach-mx2/mx21ads.c
@@ -164,25 +164,33 @@ static void mx21ads_fb_exit(struct platform_device *pdev)
164 * Connected is a portrait Sharp-QVGA display 164 * Connected is a portrait Sharp-QVGA display
165 * of type: LQ035Q7DB02 165 * of type: LQ035Q7DB02
166 */ 166 */
167static struct imx_fb_platform_data mx21ads_fb_data = { 167static struct imx_fb_videomode mx21ads_modes[] = {
168 .pixclock = 188679, /* in ps */ 168 {
169 .xres = 240, 169 .mode = {
170 .yres = 320, 170 .name = "Sharp-LQ035Q7",
171 171 .refresh = 60,
172 .bpp = 16, 172 .xres = 240,
173 .hsync_len = 2, 173 .yres = 320,
174 .left_margin = 6, 174 .pixclock = 188679, /* in ps (5.3MHz) */
175 .right_margin = 16, 175 .hsync_len = 2,
176 .left_margin = 6,
177 .right_margin = 16,
178 .vsync_len = 1,
179 .upper_margin = 8,
180 .lower_margin = 10,
181 },
182 .pcr = 0xfb108bc7,
183 .bpp = 16,
184 },
185};
176 186
177 .vsync_len = 1, 187static struct imx_fb_platform_data mx21ads_fb_data = {
178 .upper_margin = 8, 188 .mode = mx21ads_modes,
179 .lower_margin = 10, 189 .num_modes = ARRAY_SIZE(mx21ads_modes),
180 .fixed_screen_cpu = 0,
181 190
182 .pcr = 0xFB108BC7, 191 .pwmr = 0x00a903ff,
183 .pwmr = 0x00A901ff, 192 .lscr1 = 0x00120300,
184 .lscr1 = 0x00120300, 193 .dmacr = 0x00020008,
185 .dmacr = 0x00020008,
186 194
187 .init = mx21ads_fb_init, 195 .init = mx21ads_fb_init,
188 .exit = mx21ads_fb_exit, 196 .exit = mx21ads_fb_exit,
@@ -280,7 +288,7 @@ MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
280 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, 288 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
281 .boot_params = PHYS_OFFSET + 0x100, 289 .boot_params = PHYS_OFFSET + 0x100,
282 .map_io = mx21ads_map_io, 290 .map_io = mx21ads_map_io,
283 .init_irq = mxc_init_irq, 291 .init_irq = mx21_init_irq,
284 .init_machine = mx21ads_board_init, 292 .init_machine = mx21ads_board_init,
285 .timer = &mx21ads_timer, 293 .timer = &mx21ads_timer,
286MACHINE_END 294MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c
index 02daddac6995..83e412b713e6 100644
--- a/arch/arm/mach-mx2/mx27ads.c
+++ b/arch/arm/mach-mx2/mx27ads.c
@@ -183,20 +183,29 @@ void lcd_power(int on)
183 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); 183 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
184} 184}
185 185
186static struct imx_fb_platform_data mx27ads_fb_data = { 186static struct imx_fb_videomode mx27ads_modes[] = {
187 .pixclock = 188679, 187 {
188 .xres = 240, 188 .mode = {
189 .yres = 320, 189 .name = "Sharp-LQ035Q7",
190 190 .refresh = 60,
191 .bpp = 16, 191 .xres = 240,
192 .hsync_len = 1, 192 .yres = 320,
193 .left_margin = 9, 193 .pixclock = 188679, /* in ps (5.3MHz) */
194 .right_margin = 16, 194 .hsync_len = 1,
195 .left_margin = 9,
196 .right_margin = 16,
197 .vsync_len = 1,
198 .upper_margin = 7,
199 .lower_margin = 9,
200 },
201 .bpp = 16,
202 .pcr = 0xFB008BC0,
203 },
204};
195 205
196 .vsync_len = 1, 206static struct imx_fb_platform_data mx27ads_fb_data = {
197 .upper_margin = 7, 207 .mode = mx27ads_modes,
198 .lower_margin = 9, 208 .num_modes = ARRAY_SIZE(mx27ads_modes),
199 .fixed_screen_cpu = 0,
200 209
201 /* 210 /*
202 * - HSYNC active high 211 * - HSYNC active high
@@ -207,7 +216,6 @@ static struct imx_fb_platform_data mx27ads_fb_data = {
207 * - data enable low active 216 * - data enable low active
208 * - enable sharp mode 217 * - enable sharp mode
209 */ 218 */
210 .pcr = 0xFB008BC0,
211 .pwmr = 0x00A903FF, 219 .pwmr = 0x00A903FF,
212 .lscr1 = 0x00120300, 220 .lscr1 = 0x00120300,
213 .dmacr = 0x00020010, 221 .dmacr = 0x00020010,
@@ -330,7 +338,7 @@ MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
330 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, 338 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
331 .boot_params = PHYS_OFFSET + 0x100, 339 .boot_params = PHYS_OFFSET + 0x100,
332 .map_io = mx27ads_map_io, 340 .map_io = mx27ads_map_io,
333 .init_irq = mxc_init_irq, 341 .init_irq = mx27_init_irq,
334 .init_machine = mx27ads_board_init, 342 .init_machine = mx27ads_board_init,
335 .timer = &mx27ads_timer, 343 .timer = &mx27ads_timer,
336MACHINE_END 344MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27lite.c b/arch/arm/mach-mx2/mx27lite.c
index 3ae11cb8c04b..82ea227ea0cf 100644
--- a/arch/arm/mach-mx2/mx27lite.c
+++ b/arch/arm/mach-mx2/mx27lite.c
@@ -89,7 +89,7 @@ MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
89 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, 89 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
90 .boot_params = PHYS_OFFSET + 0x100, 90 .boot_params = PHYS_OFFSET + 0x100,
91 .map_io = mx27_map_io, 91 .map_io = mx27_map_io,
92 .init_irq = mxc_init_irq, 92 .init_irq = mx27_init_irq,
93 .init_machine = mx27lite_init, 93 .init_machine = mx27lite_init,
94 .timer = &mx27lite_timer, 94 .timer = &mx27lite_timer,
95MACHINE_END 95MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27pdk.c b/arch/arm/mach-mx2/mx27pdk.c
index 1d9238c7a6c3..6761d1b79e43 100644
--- a/arch/arm/mach-mx2/mx27pdk.c
+++ b/arch/arm/mach-mx2/mx27pdk.c
@@ -89,7 +89,7 @@ MACHINE_START(MX27_3DS, "Freescale MX27PDK")
89 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, 89 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
90 .boot_params = PHYS_OFFSET + 0x100, 90 .boot_params = PHYS_OFFSET + 0x100,
91 .map_io = mx27_map_io, 91 .map_io = mx27_map_io,
92 .init_irq = mxc_init_irq, 92 .init_irq = mx27_init_irq,
93 .init_machine = mx27pdk_init, 93 .init_machine = mx27pdk_init,
94 .timer = &mx27pdk_timer, 94 .timer = &mx27pdk_timer,
95MACHINE_END 95MACHINE_END
diff --git a/arch/arm/mach-mx2/pca100.c b/arch/arm/mach-mx2/pca100.c
new file mode 100644
index 000000000000..fe5b165b88cc
--- /dev/null
+++ b/arch/arm/mach-mx2/pca100.c
@@ -0,0 +1,244 @@
1/*
2 * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
3 * Copyright (C) 2009 Sascha Hauer (kernel@pengutronix.de)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#include <linux/platform_device.h>
21#include <linux/io.h>
22#include <linux/i2c.h>
23#include <linux/i2c/at24.h>
24#include <linux/dma-mapping.h>
25#include <linux/spi/spi.h>
26#include <linux/spi/eeprom.h>
27#include <linux/irq.h>
28#include <linux/gpio.h>
29
30#include <asm/mach/arch.h>
31#include <asm/mach-types.h>
32#include <mach/common.h>
33#include <mach/hardware.h>
34#include <mach/iomux.h>
35#include <mach/i2c.h>
36#include <asm/mach/time.h>
37#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
38#include <mach/spi.h>
39#endif
40#include <mach/imx-uart.h>
41#include <mach/mxc_nand.h>
42#include <mach/irqs.h>
43#include <mach/mmc.h>
44
45#include "devices.h"
46
47static int pca100_pins[] = {
48 /* UART1 */
49 PE12_PF_UART1_TXD,
50 PE13_PF_UART1_RXD,
51 PE14_PF_UART1_CTS,
52 PE15_PF_UART1_RTS,
53 /* SDHC */
54 PB4_PF_SD2_D0,
55 PB5_PF_SD2_D1,
56 PB6_PF_SD2_D2,
57 PB7_PF_SD2_D3,
58 PB8_PF_SD2_CMD,
59 PB9_PF_SD2_CLK,
60 /* FEC */
61 PD0_AIN_FEC_TXD0,
62 PD1_AIN_FEC_TXD1,
63 PD2_AIN_FEC_TXD2,
64 PD3_AIN_FEC_TXD3,
65 PD4_AOUT_FEC_RX_ER,
66 PD5_AOUT_FEC_RXD1,
67 PD6_AOUT_FEC_RXD2,
68 PD7_AOUT_FEC_RXD3,
69 PD8_AF_FEC_MDIO,
70 PD9_AIN_FEC_MDC,
71 PD10_AOUT_FEC_CRS,
72 PD11_AOUT_FEC_TX_CLK,
73 PD12_AOUT_FEC_RXD0,
74 PD13_AOUT_FEC_RX_DV,
75 PD14_AOUT_FEC_RX_CLK,
76 PD15_AOUT_FEC_COL,
77 PD16_AIN_FEC_TX_ER,
78 PF23_AIN_FEC_TX_EN,
79 /* SSI1 */
80 PC20_PF_SSI1_FS,
81 PC21_PF_SSI1_RXD,
82 PC22_PF_SSI1_TXD,
83 PC23_PF_SSI1_CLK,
84 /* onboard I2C */
85 PC5_PF_I2C2_SDA,
86 PC6_PF_I2C2_SCL,
87 /* external I2C */
88 PD17_PF_I2C_DATA,
89 PD18_PF_I2C_CLK,
90 /* SPI1 */
91 PD25_PF_CSPI1_RDY,
92 PD29_PF_CSPI1_SCLK,
93 PD30_PF_CSPI1_MISO,
94 PD31_PF_CSPI1_MOSI,
95};
96
97static struct imxuart_platform_data uart_pdata = {
98 .flags = IMXUART_HAVE_RTSCTS,
99};
100
101static struct mxc_nand_platform_data pca100_nand_board_info = {
102 .width = 1,
103 .hw_ecc = 1,
104};
105
106static struct platform_device *platform_devices[] __initdata = {
107 &mxc_w1_master_device,
108 &mxc_fec_device,
109};
110
111static struct imxi2c_platform_data pca100_i2c_1_data = {
112 .bitrate = 100000,
113};
114
115static struct at24_platform_data board_eeprom = {
116 .byte_len = 4096,
117 .page_size = 32,
118 .flags = AT24_FLAG_ADDR16,
119};
120
121static struct i2c_board_info pca100_i2c_devices[] = {
122 {
123 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
124 .platform_data = &board_eeprom,
125 }, {
126 I2C_BOARD_INFO("rtc-pcf8563", 0x51),
127 .type = "pcf8563"
128 }, {
129 I2C_BOARD_INFO("lm75", 0x4a),
130 .type = "lm75"
131 }
132};
133
134#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
135static struct spi_eeprom at25320 = {
136 .name = "at25320an",
137 .byte_len = 4096,
138 .page_size = 32,
139 .flags = EE_ADDR2,
140};
141
142static struct spi_board_info pca100_spi_board_info[] __initdata = {
143 {
144 .modalias = "at25",
145 .max_speed_hz = 30000,
146 .bus_num = 0,
147 .chip_select = 1,
148 .platform_data = &at25320,
149 },
150};
151
152static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
153
154static struct spi_imx_master pca100_spi_0_data = {
155 .chipselect = pca100_spi_cs,
156 .num_chipselect = ARRAY_SIZE(pca100_spi_cs),
157};
158#endif
159
160static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
161 void *data)
162{
163 int ret;
164
165 ret = request_irq(IRQ_GPIOC(29), detect_irq,
166 IRQF_DISABLED | IRQF_TRIGGER_FALLING,
167 "imx-mmc-detect", data);
168 if (ret)
169 printk(KERN_ERR
170 "pca100: Failed to reuest irq for sd/mmc detection\n");
171
172 return ret;
173}
174
175static void pca100_sdhc2_exit(struct device *dev, void *data)
176{
177 free_irq(IRQ_GPIOC(29), data);
178}
179
180static struct imxmmc_platform_data sdhc_pdata = {
181 .init = pca100_sdhc2_init,
182 .exit = pca100_sdhc2_exit,
183};
184
185static void __init pca100_init(void)
186{
187 int ret;
188
189 ret = mxc_gpio_setup_multiple_pins(pca100_pins,
190 ARRAY_SIZE(pca100_pins), "PCA100");
191 if (ret)
192 printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
193
194 mxc_register_device(&mxc_uart_device0, &uart_pdata);
195
196 mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
197 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
198
199 mxc_register_device(&mxc_nand_device, &pca100_nand_board_info);
200
201 /* only the i2c master 1 is used on this CPU card */
202 i2c_register_board_info(1, pca100_i2c_devices,
203 ARRAY_SIZE(pca100_i2c_devices));
204
205 mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data);
206
207 mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
208 mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT);
209
210 /* GPIO0_IRQ */
211 mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN);
212 /* GPIO1_IRQ */
213 mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN);
214 /* GPIO2_IRQ */
215 mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN);
216
217#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
218 spi_register_board_info(pca100_spi_board_info,
219 ARRAY_SIZE(pca100_spi_board_info));
220 mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
221#endif
222
223 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
224}
225
226static void __init pca100_timer_init(void)
227{
228 mx27_clocks_init(26000000);
229}
230
231static struct sys_timer pca100_timer = {
232 .init = pca100_timer_init,
233};
234
235MACHINE_START(PCA100, "phyCARD-i.MX27")
236 .phys_io = AIPI_BASE_ADDR,
237 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
238 .boot_params = PHYS_OFFSET + 0x100,
239 .map_io = mx27_map_io,
240 .init_irq = mxc_init_irq,
241 .init_machine = pca100_init,
242 .timer = &pca100_timer,
243MACHINE_END
244
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
index a4628d004343..ee65dda584cf 100644
--- a/arch/arm/mach-mx2/pcm038.c
+++ b/arch/arm/mach-mx2/pcm038.c
@@ -186,17 +186,13 @@ static struct at24_platform_data board_eeprom = {
186}; 186};
187 187
188static struct i2c_board_info pcm038_i2c_devices[] = { 188static struct i2c_board_info pcm038_i2c_devices[] = {
189 [0] = { 189 {
190 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ 190 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
191 .platform_data = &board_eeprom, 191 .platform_data = &board_eeprom,
192 }, 192 }, {
193 [1] = { 193 I2C_BOARD_INFO("pcf8563", 0x51),
194 I2C_BOARD_INFO("rtc-pcf8563", 0x51), 194 }, {
195 .type = "pcf8563"
196 },
197 [2] = {
198 I2C_BOARD_INFO("lm75", 0x4a), 195 I2C_BOARD_INFO("lm75", 0x4a),
199 .type = "lm75"
200 } 196 }
201}; 197};
202 198
@@ -220,6 +216,9 @@ static void __init pcm038_init(void)
220 216
221 mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data); 217 mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
222 218
219 /* PE18 for user-LED D40 */
220 mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
221
223 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); 222 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
224 223
225#ifdef CONFIG_MACH_PCM970_BASEBOARD 224#ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -241,7 +240,7 @@ MACHINE_START(PCM038, "phyCORE-i.MX27")
241 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, 240 .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
242 .boot_params = PHYS_OFFSET + 0x100, 241 .boot_params = PHYS_OFFSET + 0x100,
243 .map_io = mx27_map_io, 242 .map_io = mx27_map_io,
244 .init_irq = mxc_init_irq, 243 .init_irq = mx27_init_irq,
245 .init_machine = pcm038_init, 244 .init_machine = pcm038_init,
246 .timer = &pcm038_timer, 245 .timer = &pcm038_timer,
247MACHINE_END 246MACHINE_END
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c
index 6a3acaf57dd4..c261f59b0b4c 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-mx2/pcm970-baseboard.c
@@ -19,6 +19,7 @@
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/can/platform/sja1000.h>
22 23
23#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
24 25
@@ -125,40 +126,96 @@ static struct imxmmc_platform_data sdhc_pdata = {
125 .exit = pcm970_sdhc2_exit, 126 .exit = pcm970_sdhc2_exit,
126}; 127};
127 128
128/* 129static struct imx_fb_videomode pcm970_modes[] = {
129 * Connected is a portrait Sharp-QVGA display 130 {
130 * of type: LQ035Q7DH06 131 .mode = {
131 */ 132 .name = "Sharp-LQ035Q7",
132static struct imx_fb_platform_data pcm038_fb_data = { 133 .refresh = 60,
133 .pixclock = 188679, /* in ps (5.3MHz) */ 134 .xres = 240,
134 .xres = 240, 135 .yres = 320,
135 .yres = 320, 136 .pixclock = 188679, /* in ps (5.3MHz) */
136 137 .hsync_len = 7,
137 .bpp = 16, 138 .left_margin = 5,
138 .hsync_len = 7, 139 .right_margin = 16,
139 .left_margin = 5, 140 .vsync_len = 1,
140 .right_margin = 16, 141 .upper_margin = 7,
142 .lower_margin = 9,
143 },
144 /*
145 * - HSYNC active high
146 * - VSYNC active high
147 * - clk notenabled while idle
148 * - clock not inverted
149 * - data not inverted
150 * - data enable low active
151 * - enable sharp mode
152 */
153 .pcr = 0xF00080C0,
154 .bpp = 16,
155 }, {
156 .mode = {
157 .name = "TX090",
158 .refresh = 60,
159 .xres = 240,
160 .yres = 320,
161 .pixclock = 38255,
162 .left_margin = 144,
163 .right_margin = 0,
164 .upper_margin = 7,
165 .lower_margin = 40,
166 .hsync_len = 96,
167 .vsync_len = 1,
168 },
169 /*
170 * - HSYNC active low (1 << 22)
171 * - VSYNC active low (1 << 23)
172 * - clk notenabled while idle
173 * - clock not inverted
174 * - data not inverted
175 * - data enable low active
176 * - enable sharp mode
177 */
178 .pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19),
179 .bpp = 32,
180 },
181};
141 182
142 .vsync_len = 1, 183static struct imx_fb_platform_data pcm038_fb_data = {
143 .upper_margin = 7, 184 .mode = pcm970_modes,
144 .lower_margin = 9, 185 .num_modes = ARRAY_SIZE(pcm970_modes),
145 .fixed_screen_cpu = 0,
146 186
147 /*
148 * - HSYNC active high
149 * - VSYNC active high
150 * - clk notenabled while idle
151 * - clock not inverted
152 * - data not inverted
153 * - data enable low active
154 * - enable sharp mode
155 */
156 .pcr = 0xFA0080C0,
157 .pwmr = 0x00A903FF, 187 .pwmr = 0x00A903FF,
158 .lscr1 = 0x00120300, 188 .lscr1 = 0x00120300,
159 .dmacr = 0x00020010, 189 .dmacr = 0x00020010,
160}; 190};
161 191
192static struct resource pcm970_sja1000_resources[] = {
193 {
194 .start = CS4_BASE_ADDR,
195 .end = CS4_BASE_ADDR + 0x100 - 1,
196 .flags = IORESOURCE_MEM,
197 }, {
198 .start = IRQ_GPIOE(19),
199 .end = IRQ_GPIOE(19),
200 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
201 },
202};
203
204struct sja1000_platform_data pcm970_sja1000_platform_data = {
205 .clock = 16000000 / 2,
206 .ocr = 0x40 | 0x18,
207 .cdr = 0x40,
208};
209
210static struct platform_device pcm970_sja1000 = {
211 .name = "sja1000_platform",
212 .dev = {
213 .platform_data = &pcm970_sja1000_platform_data,
214 },
215 .resource = pcm970_sja1000_resources,
216 .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
217};
218
162/* 219/*
163 * system init for baseboard usage. Will be called by pcm038 init. 220 * system init for baseboard usage. Will be called by pcm038 init.
164 * 221 *
@@ -172,4 +229,5 @@ void __init pcm970_baseboard_init(void)
172 229
173 mxc_register_device(&mxc_fb_device, &pcm038_fb_data); 230 mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
174 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata); 231 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
232 platform_device_register(&pcm970_sja1000);
175} 233}
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
new file mode 100644
index 000000000000..cc28f56eae80
--- /dev/null
+++ b/arch/arm/mach-mx25/Kconfig
@@ -0,0 +1,9 @@
1if ARCH_MX25
2
3comment "MX25 platforms:"
4
5config MACH_MX25_3DS
6 select ARCH_MXC_IOMUX_V3
7 bool "Support MX25PDK (3DS) Platform"
8
9endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
new file mode 100644
index 000000000000..fe23836a9f3d
--- /dev/null
+++ b/arch/arm/mach-mx25/Makefile
@@ -0,0 +1,3 @@
1obj-y := mm.o devices.o
2obj-$(CONFIG_ARCH_MX25) += clock.o
3obj-$(CONFIG_MACH_MX25_3DS) += mx25pdk.o
diff --git a/arch/arm/mach-mx25/Makefile.boot b/arch/arm/mach-mx25/Makefile.boot
new file mode 100644
index 000000000000..e1dd366f836b
--- /dev/null
+++ b/arch/arm/mach-mx25/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x80008000
2params_phys-y := 0x80000100
3initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
new file mode 100644
index 000000000000..ef26951a5275
--- /dev/null
+++ b/arch/arm/mach-mx25/clock.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24
25#include <asm/clkdev.h>
26
27#include <mach/clock.h>
28#include <mach/hardware.h>
29#include <mach/common.h>
30#include <mach/mx25.h>
31
32#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
33
34#define CCM_MPCTL 0x00
35#define CCM_UPCTL 0x04
36#define CCM_CCTL 0x08
37#define CCM_CGCR0 0x0C
38#define CCM_CGCR1 0x10
39#define CCM_CGCR2 0x14
40#define CCM_PCDR0 0x18
41#define CCM_PCDR1 0x1C
42#define CCM_PCDR2 0x20
43#define CCM_PCDR3 0x24
44#define CCM_RCSR 0x28
45#define CCM_CRDR 0x2C
46#define CCM_DCVR0 0x30
47#define CCM_DCVR1 0x34
48#define CCM_DCVR2 0x38
49#define CCM_DCVR3 0x3c
50#define CCM_LTR0 0x40
51#define CCM_LTR1 0x44
52#define CCM_LTR2 0x48
53#define CCM_LTR3 0x4c
54
55static unsigned long get_rate_mpll(void)
56{
57 ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
58
59 return mxc_decode_pll(mpctl, 24000000);
60}
61
62static unsigned long get_rate_upll(void)
63{
64 ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
65
66 return mxc_decode_pll(mpctl, 24000000);
67}
68
69unsigned long get_rate_arm(struct clk *clk)
70{
71 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
72 unsigned long rate = get_rate_mpll();
73
74 if (cctl & (1 << 14))
75 rate = (rate * 3) >> 1;
76
77 return rate / ((cctl >> 30) + 1);
78}
79
80static unsigned long get_rate_ahb(struct clk *clk)
81{
82 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
83
84 return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
85}
86
87static unsigned long get_rate_ipg(struct clk *clk)
88{
89 return get_rate_ahb(NULL) >> 1;
90}
91
92static unsigned long get_rate_per(int per)
93{
94 unsigned long ofs = (per & 0x3) * 8;
95 unsigned long reg = per & ~0x3;
96 unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
97 unsigned long fref;
98
99 if (readl(CRM_BASE + 0x64) & (1 << per))
100 fref = get_rate_upll();
101 else
102 fref = get_rate_ipg(NULL);
103
104 return fref / (val + 1);
105}
106
107static unsigned long get_rate_uart(struct clk *clk)
108{
109 return get_rate_per(15);
110}
111
112static unsigned long get_rate_i2c(struct clk *clk)
113{
114 return get_rate_per(6);
115}
116
117static unsigned long get_rate_nfc(struct clk *clk)
118{
119 return get_rate_per(8);
120}
121
122static unsigned long get_rate_otg(struct clk *clk)
123{
124 return 48000000; /* FIXME */
125}
126
127static int clk_cgcr_enable(struct clk *clk)
128{
129 u32 reg;
130
131 reg = __raw_readl(clk->enable_reg);
132 reg |= 1 << clk->enable_shift;
133 __raw_writel(reg, clk->enable_reg);
134
135 return 0;
136}
137
138static void clk_cgcr_disable(struct clk *clk)
139{
140 u32 reg;
141
142 reg = __raw_readl(clk->enable_reg);
143 reg &= ~(1 << clk->enable_shift);
144 __raw_writel(reg, clk->enable_reg);
145}
146
147#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
148 static struct clk name = { \
149 .id = i, \
150 .enable_reg = CRM_BASE + er, \
151 .enable_shift = es, \
152 .get_rate = gr, \
153 .set_rate = sr, \
154 .enable = clk_cgcr_enable, \
155 .disable = clk_cgcr_disable, \
156 }
157
158DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_ipg, NULL);
159DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL);
160DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL);
161DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL);
162DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL);
163DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL);
164DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL);
165DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL);
166DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL);
167DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL);
168DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL);
169DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL);
170DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL);
171DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL);
172DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL);
173DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL);
174DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL);
175DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL);
176
177#define _REGISTER_CLOCK(d, n, c) \
178 { \
179 .dev_id = d, \
180 .con_id = n, \
181 .clk = &c, \
182 },
183
184static struct clk_lookup lookups[] = {
185 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
186 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
187 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
188 _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
189 _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
190 _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
191 _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
192 _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
193 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
194 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
195 _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
196 _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
197 _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
198 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
199 _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
200 _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
201 _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
202 _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
203 _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
204 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
205 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
206 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
207};
208
209int __init mx25_clocks_init(unsigned long fref)
210{
211 int i;
212
213 for (i = 0; i < ARRAY_SIZE(lookups); i++)
214 clkdev_add(&lookups[i]);
215
216 mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
217
218 return 0;
219}
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
new file mode 100644
index 000000000000..eb12de1da42d
--- /dev/null
+++ b/arch/arm/mach-mx25/devices.c
@@ -0,0 +1,402 @@
1#include <linux/platform_device.h>
2#include <linux/gpio.h>
3#include <mach/mx25.h>
4#include <mach/irqs.h>
5
6static struct resource uart0[] = {
7 {
8 .start = 0x43f90000,
9 .end = 0x43f93fff,
10 .flags = IORESOURCE_MEM,
11 }, {
12 .start = 45,
13 .end = 45,
14 .flags = IORESOURCE_IRQ,
15 },
16};
17
18struct platform_device mxc_uart_device0 = {
19 .name = "imx-uart",
20 .id = 0,
21 .resource = uart0,
22 .num_resources = ARRAY_SIZE(uart0),
23};
24
25static struct resource uart1[] = {
26 {
27 .start = 0x43f94000,
28 .end = 0x43f97fff,
29 .flags = IORESOURCE_MEM,
30 }, {
31 .start = 32,
32 .end = 32,
33 .flags = IORESOURCE_IRQ,
34 },
35};
36
37struct platform_device mxc_uart_device1 = {
38 .name = "imx-uart",
39 .id = 1,
40 .resource = uart1,
41 .num_resources = ARRAY_SIZE(uart1),
42};
43
44static struct resource uart2[] = {
45 {
46 .start = 0x5000c000,
47 .end = 0x5000ffff,
48 .flags = IORESOURCE_MEM,
49 }, {
50 .start = 18,
51 .end = 18,
52 .flags = IORESOURCE_IRQ,
53 },
54};
55
56struct platform_device mxc_uart_device2 = {
57 .name = "imx-uart",
58 .id = 2,
59 .resource = uart2,
60 .num_resources = ARRAY_SIZE(uart2),
61};
62
63static struct resource uart3[] = {
64 {
65 .start = 0x50008000,
66 .end = 0x5000bfff,
67 .flags = IORESOURCE_MEM,
68 }, {
69 .start = 5,
70 .end = 5,
71 .flags = IORESOURCE_IRQ,
72 },
73};
74
75struct platform_device mxc_uart_device3 = {
76 .name = "imx-uart",
77 .id = 3,
78 .resource = uart3,
79 .num_resources = ARRAY_SIZE(uart3),
80};
81
82static struct resource uart4[] = {
83 {
84 .start = 0x5002c000,
85 .end = 0x5002ffff,
86 .flags = IORESOURCE_MEM,
87 }, {
88 .start = 40,
89 .end = 40,
90 .flags = IORESOURCE_IRQ,
91 },
92};
93
94struct platform_device mxc_uart_device4 = {
95 .name = "imx-uart",
96 .id = 4,
97 .resource = uart4,
98 .num_resources = ARRAY_SIZE(uart4),
99};
100
101#define MX25_OTG_BASE_ADDR 0x53FF4000
102
103static u64 otg_dmamask = DMA_BIT_MASK(32);
104
105static struct resource mxc_otg_resources[] = {
106 {
107 .start = MX25_OTG_BASE_ADDR,
108 .end = MX25_OTG_BASE_ADDR + 0x1ff,
109 .flags = IORESOURCE_MEM,
110 }, {
111 .start = 37,
112 .end = 37,
113 .flags = IORESOURCE_IRQ,
114 },
115};
116
117struct platform_device mxc_otg = {
118 .name = "mxc-ehci",
119 .id = 0,
120 .dev = {
121 .coherent_dma_mask = 0xffffffff,
122 .dma_mask = &otg_dmamask,
123 },
124 .resource = mxc_otg_resources,
125 .num_resources = ARRAY_SIZE(mxc_otg_resources),
126};
127
128/* OTG gadget device */
129struct platform_device otg_udc_device = {
130 .name = "fsl-usb2-udc",
131 .id = -1,
132 .dev = {
133 .dma_mask = &otg_dmamask,
134 .coherent_dma_mask = 0xffffffff,
135 },
136 .resource = mxc_otg_resources,
137 .num_resources = ARRAY_SIZE(mxc_otg_resources),
138};
139
140static u64 usbh2_dmamask = DMA_BIT_MASK(32);
141
142static struct resource mxc_usbh2_resources[] = {
143 {
144 .start = MX25_OTG_BASE_ADDR + 0x400,
145 .end = MX25_OTG_BASE_ADDR + 0x5ff,
146 .flags = IORESOURCE_MEM,
147 }, {
148 .start = 35,
149 .end = 35,
150 .flags = IORESOURCE_IRQ,
151 },
152};
153
154struct platform_device mxc_usbh2 = {
155 .name = "mxc-ehci",
156 .id = 1,
157 .dev = {
158 .coherent_dma_mask = 0xffffffff,
159 .dma_mask = &usbh2_dmamask,
160 },
161 .resource = mxc_usbh2_resources,
162 .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
163};
164
165static struct resource mxc_spi_resources0[] = {
166 {
167 .start = 0x43fa4000,
168 .end = 0x43fa7fff,
169 .flags = IORESOURCE_MEM,
170 }, {
171 .start = 14,
172 .end = 14,
173 .flags = IORESOURCE_IRQ,
174 },
175};
176
177struct platform_device mxc_spi_device0 = {
178 .name = "spi_imx",
179 .id = 0,
180 .num_resources = ARRAY_SIZE(mxc_spi_resources0),
181 .resource = mxc_spi_resources0,
182};
183
184static struct resource mxc_spi_resources1[] = {
185 {
186 .start = 0x50010000,
187 .end = 0x50013fff,
188 .flags = IORESOURCE_MEM,
189 }, {
190 .start = 13,
191 .end = 13,
192 .flags = IORESOURCE_IRQ,
193 },
194};
195
196struct platform_device mxc_spi_device1 = {
197 .name = "spi_imx",
198 .id = 1,
199 .num_resources = ARRAY_SIZE(mxc_spi_resources1),
200 .resource = mxc_spi_resources1,
201};
202
203static struct resource mxc_spi_resources2[] = {
204 {
205 .start = 0x50004000,
206 .end = 0x50007fff,
207 .flags = IORESOURCE_MEM,
208 }, {
209 .start = 0,
210 .end = 0,
211 .flags = IORESOURCE_IRQ,
212 },
213};
214
215struct platform_device mxc_spi_device2 = {
216 .name = "spi_imx",
217 .id = 2,
218 .num_resources = ARRAY_SIZE(mxc_spi_resources2),
219 .resource = mxc_spi_resources2,
220};
221
222static struct resource mxc_pwm_resources0[] = {
223 {
224 .start = 0x53fe0000,
225 .end = 0x53fe3fff,
226 .flags = IORESOURCE_MEM,
227 }, {
228 .start = 26,
229 .end = 26,
230 .flags = IORESOURCE_IRQ,
231 }
232};
233
234struct platform_device mxc_pwm_device0 = {
235 .name = "mxc_pwm",
236 .id = 0,
237 .num_resources = ARRAY_SIZE(mxc_pwm_resources0),
238 .resource = mxc_pwm_resources0,
239};
240
241static struct resource mxc_pwm_resources1[] = {
242 {
243 .start = 0x53fa0000,
244 .end = 0x53fa3fff,
245 .flags = IORESOURCE_MEM,
246 }, {
247 .start = 36,
248 .end = 36,
249 .flags = IORESOURCE_IRQ,
250 }
251};
252
253struct platform_device mxc_pwm_device1 = {
254 .name = "mxc_pwm",
255 .id = 1,
256 .num_resources = ARRAY_SIZE(mxc_pwm_resources1),
257 .resource = mxc_pwm_resources1,
258};
259
260static struct resource mxc_pwm_resources2[] = {
261 {
262 .start = 0x53fa8000,
263 .end = 0x53fabfff,
264 .flags = IORESOURCE_MEM,
265 }, {
266 .start = 41,
267 .end = 41,
268 .flags = IORESOURCE_IRQ,
269 }
270};
271
272struct platform_device mxc_pwm_device2 = {
273 .name = "mxc_pwm",
274 .id = 2,
275 .num_resources = ARRAY_SIZE(mxc_pwm_resources2),
276 .resource = mxc_pwm_resources2,
277};
278
279static struct resource mxc_keypad_resources[] = {
280 {
281 .start = 0x43fa8000,
282 .end = 0x43fabfff,
283 .flags = IORESOURCE_MEM,
284 }, {
285 .start = 24,
286 .end = 24,
287 .flags = IORESOURCE_IRQ,
288 }
289};
290
291struct platform_device mxc_keypad_device = {
292 .name = "mxc-keypad",
293 .id = -1,
294 .num_resources = ARRAY_SIZE(mxc_keypad_resources),
295 .resource = mxc_keypad_resources,
296};
297
298static struct resource mxc_pwm_resources3[] = {
299 {
300 .start = 0x53fc8000,
301 .end = 0x53fcbfff,
302 .flags = IORESOURCE_MEM,
303 }, {
304 .start = 42,
305 .end = 42,
306 .flags = IORESOURCE_IRQ,
307 }
308};
309
310struct platform_device mxc_pwm_device3 = {
311 .name = "mxc_pwm",
312 .id = 3,
313 .num_resources = ARRAY_SIZE(mxc_pwm_resources3),
314 .resource = mxc_pwm_resources3,
315};
316
317static struct resource mxc_i2c_1_resources[] = {
318 {
319 .start = 0x43f80000,
320 .end = 0x43f83fff,
321 .flags = IORESOURCE_MEM,
322 }, {
323 .start = 3,
324 .end = 3,
325 .flags = IORESOURCE_IRQ,
326 }
327};
328
329struct platform_device mxc_i2c_device0 = {
330 .name = "imx-i2c",
331 .id = 0,
332 .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
333 .resource = mxc_i2c_1_resources,
334};
335
336static struct resource mxc_i2c_2_resources[] = {
337 {
338 .start = 0x43f98000,
339 .end = 0x43f9bfff,
340 .flags = IORESOURCE_MEM,
341 }, {
342 .start = 4,
343 .end = 4,
344 .flags = IORESOURCE_IRQ,
345 }
346};
347
348struct platform_device mxc_i2c_device1 = {
349 .name = "imx-i2c",
350 .id = 1,
351 .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
352 .resource = mxc_i2c_2_resources,
353};
354
355static struct resource mxc_i2c_3_resources[] = {
356 {
357 .start = 0x43f84000,
358 .end = 0x43f87fff,
359 .flags = IORESOURCE_MEM,
360 }, {
361 .start = 10,
362 .end = 10,
363 .flags = IORESOURCE_IRQ,
364 }
365};
366
367struct platform_device mxc_i2c_device2 = {
368 .name = "imx-i2c",
369 .id = 2,
370 .num_resources = ARRAY_SIZE(mxc_i2c_3_resources),
371 .resource = mxc_i2c_3_resources,
372};
373
374static struct mxc_gpio_port imx_gpio_ports[] = {
375 {
376 .chip.label = "gpio-0",
377 .base = (void __iomem *)MX25_GPIO1_BASE_ADDR_VIRT,
378 .irq = 52,
379 .virtual_irq_start = MXC_GPIO_IRQ_START,
380 }, {
381 .chip.label = "gpio-1",
382 .base = (void __iomem *)MX25_GPIO2_BASE_ADDR_VIRT,
383 .irq = 51,
384 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
385 }, {
386 .chip.label = "gpio-2",
387 .base = (void __iomem *)MX25_GPIO3_BASE_ADDR_VIRT,
388 .irq = 16,
389 .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
390 }, {
391 .chip.label = "gpio-3",
392 .base = (void __iomem *)MX25_GPIO4_BASE_ADDR_VIRT,
393 .irq = 23,
394 .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
395 }
396};
397
398int __init mxc_register_gpios(void)
399{
400 return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
401}
402
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
new file mode 100644
index 000000000000..fe6bf88ad1dd
--- /dev/null
+++ b/arch/arm/mach-mx25/devices.h
@@ -0,0 +1,19 @@
1extern struct platform_device mxc_uart_device0;
2extern struct platform_device mxc_uart_device1;
3extern struct platform_device mxc_uart_device2;
4extern struct platform_device mxc_uart_device3;
5extern struct platform_device mxc_uart_device4;
6extern struct platform_device mxc_otg;
7extern struct platform_device otg_udc_device;
8extern struct platform_device mxc_usbh2;
9extern struct platform_device mxc_spi_device0;
10extern struct platform_device mxc_spi_device1;
11extern struct platform_device mxc_spi_device2;
12extern struct platform_device mxc_pwm_device0;
13extern struct platform_device mxc_pwm_device1;
14extern struct platform_device mxc_pwm_device2;
15extern struct platform_device mxc_pwm_device3;
16extern struct platform_device mxc_keypad_device;
17extern struct platform_device mxc_i2c_device0;
18extern struct platform_device mxc_i2c_device1;
19extern struct platform_device mxc_i2c_device2;
diff --git a/arch/arm/mach-mx25/mm.c b/arch/arm/mach-mx25/mm.c
new file mode 100644
index 000000000000..a7e587ff3e9e
--- /dev/null
+++ b/arch/arm/mach-mx25/mm.c
@@ -0,0 +1,76 @@
1/*
2 * Copyright (C) 1999,2000 Arm Limited
3 * Copyright (C) 2000 Deep Blue Solutions Ltd
4 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
5 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
6 * - add MX31 specific definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/mm.h>
24#include <linux/init.h>
25#include <linux/err.h>
26
27#include <asm/pgtable.h>
28#include <asm/mach/map.h>
29
30#include <mach/common.h>
31#include <mach/hardware.h>
32#include <mach/mx25.h>
33#include <mach/iomux-v3.h>
34
35/*
36 * This table defines static virtual address mappings for I/O regions.
37 * These are the mappings common across all MX3 boards.
38 */
39static struct map_desc mxc_io_desc[] __initdata = {
40 {
41 .virtual = MX25_AVIC_BASE_ADDR_VIRT,
42 .pfn = __phys_to_pfn(MX25_AVIC_BASE_ADDR),
43 .length = MX25_AVIC_SIZE,
44 .type = MT_DEVICE_NONSHARED
45 }, {
46 .virtual = MX25_AIPS1_BASE_ADDR_VIRT,
47 .pfn = __phys_to_pfn(MX25_AIPS1_BASE_ADDR),
48 .length = MX25_AIPS1_SIZE,
49 .type = MT_DEVICE_NONSHARED
50 }, {
51 .virtual = MX25_AIPS2_BASE_ADDR_VIRT,
52 .pfn = __phys_to_pfn(MX25_AIPS2_BASE_ADDR),
53 .length = MX25_AIPS2_SIZE,
54 .type = MT_DEVICE_NONSHARED
55 },
56};
57
58/*
59 * This function initializes the memory map. It is called during the
60 * system startup to create static physical to virtual memory mappings
61 * for the IO modules.
62 */
63void __init mx25_map_io(void)
64{
65 mxc_set_cpu_type(MXC_CPU_MX25);
66 mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
67 mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
68
69 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
70}
71
72void __init mx25_init_irq(void)
73{
74 mxc_init_irq((void __iomem *)MX25_AVIC_BASE_ADDR_VIRT);
75}
76
diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c
new file mode 100644
index 000000000000..92aa4fd19d99
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25pdk.c
@@ -0,0 +1,58 @@
1#include <linux/types.h>
2#include <linux/init.h>
3#include <linux/clk.h>
4#include <linux/irq.h>
5#include <linux/gpio.h>
6#include <linux/smsc911x.h>
7#include <linux/platform_device.h>
8
9#include <mach/hardware.h>
10#include <asm/mach-types.h>
11#include <asm/mach/arch.h>
12#include <asm/mach/time.h>
13#include <asm/memory.h>
14#include <asm/mach/map.h>
15#include <mach/common.h>
16#include <mach/imx-uart.h>
17#include <mach/mx25.h>
18#include <mach/mxc_nand.h>
19#include "devices.h"
20#include <mach/iomux-v3.h>
21
22static struct imxuart_platform_data uart_pdata = {
23 .flags = IMXUART_HAVE_RTSCTS,
24};
25
26static struct mxc_nand_platform_data nand_board_info = {
27 .width = 1,
28 .hw_ecc = 1,
29};
30
31static void __init mx25pdk_init(void)
32{
33 mxc_register_device(&mxc_uart_device0, &uart_pdata);
34 mxc_register_device(&mxc_usbh2, NULL);
35 mxc_register_device(&mxc_nand_device, &nand_board_info);
36}
37
38
39static void __init mx25pdk_timer_init(void)
40{
41 mx25_clocks_init(26000000);
42}
43
44static struct sys_timer mx25pdk_timer = {
45 .init = mx25pdk_timer_init,
46};
47
48MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
49 /* Maintainer: Freescale Semiconductor, Inc. */
50 .phys_io = MX25_AIPS1_BASE_ADDR,
51 .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
52 .boot_params = PHYS_OFFSET + 0x100,
53 .map_io = mx25_map_io,
54 .init_irq = mx25_init_irq,
55 .init_machine = mx25pdk_init,
56 .timer = &mx25pdk_timer,
57MACHINE_END
58
diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c
index ee331fd6b1bd..776c0ee1b3cd 100644
--- a/arch/arm/mach-mx3/armadillo5x0.c
+++ b/arch/arm/mach-mx3/armadillo5x0.c
@@ -352,7 +352,7 @@ MACHINE_START(ARMADILLO5X0, "Armadillo-500")
352 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 352 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
353 .boot_params = PHYS_OFFSET + 0x00000100, 353 .boot_params = PHYS_OFFSET + 0x00000100,
354 .map_io = mx31_map_io, 354 .map_io = mx31_map_io,
355 .init_irq = mxc_init_irq, 355 .init_irq = mx31_init_irq,
356 .timer = &armadillo5x0_timer, 356 .timer = &armadillo5x0_timer,
357 .init_machine = armadillo5x0_init, 357 .init_machine = armadillo5x0_init,
358MACHINE_END 358MACHINE_END
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 577ee83d1f60..fe5c4217322e 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -273,6 +273,19 @@ static unsigned long get_rate_csi(struct clk *clk)
273 return rate / get_3_3_div((pdr2 >> 16) & 0x3f); 273 return rate / get_3_3_div((pdr2 >> 16) & 0x3f);
274} 274}
275 275
276static unsigned long get_rate_otg(struct clk *clk)
277{
278 unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
279 unsigned long rate;
280
281 if (pdr4 & (1 << 9))
282 rate = get_rate_arm();
283 else
284 rate = get_rate_ppll();
285
286 return rate / get_3_3_div((pdr4 >> 22) & 0x3f);
287}
288
276static unsigned long get_rate_ipg_per(struct clk *clk) 289static unsigned long get_rate_ipg_per(struct clk *clk)
277{ 290{
278 unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); 291 unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
@@ -365,7 +378,7 @@ DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL);
365DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); 378DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL);
366DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); 379DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL);
367DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); 380DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL);
368DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL); 381DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
369DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); 382DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL);
370DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); 383DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL);
371DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL); 384DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL);
@@ -426,7 +439,10 @@ static struct clk_lookup lookups[] = {
426 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) 439 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
427 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) 440 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
428 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) 441 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
429 _REGISTER_CLOCK(NULL, "usbotg", usbotg_clk) 442 _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
443 _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
444 _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
445 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
430 _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk) 446 _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
431 _REGISTER_CLOCK(NULL, "max", max_clk) 447 _REGISTER_CLOCK(NULL, "max", max_clk)
432 _REGISTER_CLOCK(NULL, "admux", admux_clk) 448 _REGISTER_CLOCK(NULL, "admux", admux_clk)
@@ -456,7 +472,7 @@ int __init mx35_clocks_init()
456 __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); 472 __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
457 __raw_writel(0, CCM_BASE + CCM_CGR3); 473 __raw_writel(0, CCM_BASE + CCM_CGR3);
458 474
459 mxc_timer_init(&gpt_clk); 475 mxc_timer_init(&gpt_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
460 476
461 return 0; 477 return 0;
462} 478}
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index 8b14239724c9..06bd6180bfc3 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -29,6 +29,7 @@
29 29
30#include <mach/clock.h> 30#include <mach/clock.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/mx31.h>
32#include <mach/common.h> 33#include <mach/common.h>
33 34
34#include "crm_regs.h" 35#include "crm_regs.h"
@@ -402,6 +403,11 @@ static unsigned long clk_ckih_get_rate(struct clk *clk)
402 return ckih_rate; 403 return ckih_rate;
403} 404}
404 405
406static unsigned long clk_ckil_get_rate(struct clk *clk)
407{
408 return CKIL_CLK_FREQ;
409}
410
405static struct clk ckih_clk = { 411static struct clk ckih_clk = {
406 .get_rate = clk_ckih_get_rate, 412 .get_rate = clk_ckih_get_rate,
407}; 413};
@@ -508,6 +514,7 @@ DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk)
508DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); 514DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
509DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); 515DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
510DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); 516DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
517DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
511 518
512#define _REGISTER_CLOCK(d, n, c) \ 519#define _REGISTER_CLOCK(d, n, c) \
513 { \ 520 { \
@@ -518,9 +525,9 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
518 525
519static struct clk_lookup lookups[] = { 526static struct clk_lookup lookups[] = {
520 _REGISTER_CLOCK(NULL, "emi", emi_clk) 527 _REGISTER_CLOCK(NULL, "emi", emi_clk)
521 _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) 528 _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
522 _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) 529 _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
523 _REGISTER_CLOCK(NULL, "cspi", cspi3_clk) 530 _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
524 _REGISTER_CLOCK(NULL, "gpt", gpt_clk) 531 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
525 _REGISTER_CLOCK(NULL, "pwm", pwm_clk) 532 _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
526 _REGISTER_CLOCK(NULL, "wdog", wdog_clk) 533 _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
@@ -531,6 +538,12 @@ static struct clk_lookup lookups[] = {
531 _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) 538 _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
532 _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) 539 _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
533 _REGISTER_CLOCK(NULL, "kpp", kpp_clk) 540 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
541 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
542 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
543 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
544 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
545 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
546 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
534 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) 547 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
535 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) 548 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
536 _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) 549 _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
@@ -559,6 +572,7 @@ static struct clk_lookup lookups[] = {
559 _REGISTER_CLOCK(NULL, "iim", iim_clk) 572 _REGISTER_CLOCK(NULL, "iim", iim_clk)
560 _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) 573 _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
561 _REGISTER_CLOCK(NULL, "mbx", mbx_clk) 574 _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
575 _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
562}; 576};
563 577
564int __init mx31_clocks_init(unsigned long fref) 578int __init mx31_clocks_init(unsigned long fref)
@@ -609,7 +623,7 @@ int __init mx31_clocks_init(unsigned long fref)
609 __raw_writel(reg, MXC_CCM_PMCR1); 623 __raw_writel(reg, MXC_CCM_PMCR1);
610 } 624 }
611 625
612 mxc_timer_init(&ipg_clk); 626 mxc_timer_init(&ipg_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
613 627
614 return 0; 628 return 0;
615} 629}
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index 9e87e08fb121..8a577f367250 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -129,19 +129,17 @@ struct platform_device mxc_uart_device4 = {
129 129
130/* GPIO port description */ 130/* GPIO port description */
131static struct mxc_gpio_port imx_gpio_ports[] = { 131static struct mxc_gpio_port imx_gpio_ports[] = {
132 [0] = { 132 {
133 .chip.label = "gpio-0", 133 .chip.label = "gpio-0",
134 .base = IO_ADDRESS(GPIO1_BASE_ADDR), 134 .base = IO_ADDRESS(GPIO1_BASE_ADDR),
135 .irq = MXC_INT_GPIO1, 135 .irq = MXC_INT_GPIO1,
136 .virtual_irq_start = MXC_GPIO_IRQ_START, 136 .virtual_irq_start = MXC_GPIO_IRQ_START,
137 }, 137 }, {
138 [1] = {
139 .chip.label = "gpio-1", 138 .chip.label = "gpio-1",
140 .base = IO_ADDRESS(GPIO2_BASE_ADDR), 139 .base = IO_ADDRESS(GPIO2_BASE_ADDR),
141 .irq = MXC_INT_GPIO2, 140 .irq = MXC_INT_GPIO2,
142 .virtual_irq_start = MXC_GPIO_IRQ_START + 32, 141 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
143 }, 142 }, {
144 [2] = {
145 .chip.label = "gpio-2", 143 .chip.label = "gpio-2",
146 .base = IO_ADDRESS(GPIO3_BASE_ADDR), 144 .base = IO_ADDRESS(GPIO3_BASE_ADDR),
147 .irq = MXC_INT_GPIO3, 145 .irq = MXC_INT_GPIO3,
@@ -173,11 +171,11 @@ static struct resource mxc_nand_resources[] = {
173 { 171 {
174 .start = 0, /* runtime dependent */ 172 .start = 0, /* runtime dependent */
175 .end = 0, 173 .end = 0,
176 .flags = IORESOURCE_MEM 174 .flags = IORESOURCE_MEM,
177 }, { 175 }, {
178 .start = MXC_INT_NANDFC, 176 .start = MXC_INT_NANDFC,
179 .end = MXC_INT_NANDFC, 177 .end = MXC_INT_NANDFC,
180 .flags = IORESOURCE_IRQ 178 .flags = IORESOURCE_IRQ,
181 }, 179 },
182}; 180};
183 181
@@ -193,8 +191,7 @@ static struct resource mxc_i2c0_resources[] = {
193 .start = I2C_BASE_ADDR, 191 .start = I2C_BASE_ADDR,
194 .end = I2C_BASE_ADDR + SZ_4K - 1, 192 .end = I2C_BASE_ADDR + SZ_4K - 1,
195 .flags = IORESOURCE_MEM, 193 .flags = IORESOURCE_MEM,
196 }, 194 }, {
197 {
198 .start = MXC_INT_I2C, 195 .start = MXC_INT_I2C,
199 .end = MXC_INT_I2C, 196 .end = MXC_INT_I2C,
200 .flags = IORESOURCE_IRQ, 197 .flags = IORESOURCE_IRQ,
@@ -213,8 +210,7 @@ static struct resource mxc_i2c1_resources[] = {
213 .start = I2C2_BASE_ADDR, 210 .start = I2C2_BASE_ADDR,
214 .end = I2C2_BASE_ADDR + SZ_4K - 1, 211 .end = I2C2_BASE_ADDR + SZ_4K - 1,
215 .flags = IORESOURCE_MEM, 212 .flags = IORESOURCE_MEM,
216 }, 213 }, {
217 {
218 .start = MXC_INT_I2C2, 214 .start = MXC_INT_I2C2,
219 .end = MXC_INT_I2C2, 215 .end = MXC_INT_I2C2,
220 .flags = IORESOURCE_IRQ, 216 .flags = IORESOURCE_IRQ,
@@ -233,8 +229,7 @@ static struct resource mxc_i2c2_resources[] = {
233 .start = I2C3_BASE_ADDR, 229 .start = I2C3_BASE_ADDR,
234 .end = I2C3_BASE_ADDR + SZ_4K - 1, 230 .end = I2C3_BASE_ADDR + SZ_4K - 1,
235 .flags = IORESOURCE_MEM, 231 .flags = IORESOURCE_MEM,
236 }, 232 }, {
237 {
238 .start = MXC_INT_I2C3, 233 .start = MXC_INT_I2C3,
239 .end = MXC_INT_I2C3, 234 .end = MXC_INT_I2C3,
240 .flags = IORESOURCE_IRQ, 235 .flags = IORESOURCE_IRQ,
@@ -371,8 +366,8 @@ struct platform_device mx3_camera = {
371 366
372static struct resource otg_resources[] = { 367static struct resource otg_resources[] = {
373 { 368 {
374 .start = OTG_BASE_ADDR, 369 .start = MX31_OTG_BASE_ADDR,
375 .end = OTG_BASE_ADDR + 0x1ff, 370 .end = MX31_OTG_BASE_ADDR + 0x1ff,
376 .flags = IORESOURCE_MEM, 371 .flags = IORESOURCE_MEM,
377 }, { 372 }, {
378 .start = MXC_INT_USB3, 373 .start = MXC_INT_USB3,
@@ -395,16 +390,142 @@ struct platform_device mxc_otg_udc_device = {
395 .num_resources = ARRAY_SIZE(otg_resources), 390 .num_resources = ARRAY_SIZE(otg_resources),
396}; 391};
397 392
393/* OTG host */
394struct platform_device mxc_otg_host = {
395 .name = "mxc-ehci",
396 .id = 0,
397 .dev = {
398 .coherent_dma_mask = 0xffffffff,
399 .dma_mask = &otg_dmamask,
400 },
401 .resource = otg_resources,
402 .num_resources = ARRAY_SIZE(otg_resources),
403};
404
405/* USB host 1 */
406
407static u64 usbh1_dmamask = ~(u32)0;
408
409static struct resource mxc_usbh1_resources[] = {
410 {
411 .start = MX31_OTG_BASE_ADDR + 0x200,
412 .end = MX31_OTG_BASE_ADDR + 0x3ff,
413 .flags = IORESOURCE_MEM,
414 }, {
415 .start = MXC_INT_USB1,
416 .end = MXC_INT_USB1,
417 .flags = IORESOURCE_IRQ,
418 },
419};
420
421struct platform_device mxc_usbh1 = {
422 .name = "mxc-ehci",
423 .id = 1,
424 .dev = {
425 .coherent_dma_mask = 0xffffffff,
426 .dma_mask = &usbh1_dmamask,
427 },
428 .resource = mxc_usbh1_resources,
429 .num_resources = ARRAY_SIZE(mxc_usbh1_resources),
430};
431
432/* USB host 2 */
433static u64 usbh2_dmamask = ~(u32)0;
434
435static struct resource mxc_usbh2_resources[] = {
436 {
437 .start = MX31_OTG_BASE_ADDR + 0x400,
438 .end = MX31_OTG_BASE_ADDR + 0x5ff,
439 .flags = IORESOURCE_MEM,
440 }, {
441 .start = MXC_INT_USB2,
442 .end = MXC_INT_USB2,
443 .flags = IORESOURCE_IRQ,
444 },
445};
446
447struct platform_device mxc_usbh2 = {
448 .name = "mxc-ehci",
449 .id = 2,
450 .dev = {
451 .coherent_dma_mask = 0xffffffff,
452 .dma_mask = &usbh2_dmamask,
453 },
454 .resource = mxc_usbh2_resources,
455 .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
456};
457
458/*
459 * SPI master controller
460 * 3 channels
461 */
462static struct resource imx_spi_0_resources[] = {
463 {
464 .start = CSPI1_BASE_ADDR,
465 .end = CSPI1_BASE_ADDR + SZ_4K - 1,
466 .flags = IORESOURCE_MEM,
467 }, {
468 .start = MXC_INT_CSPI1,
469 .end = MXC_INT_CSPI1,
470 .flags = IORESOURCE_IRQ,
471 },
472};
473
474static struct resource imx_spi_1_resources[] = {
475 {
476 .start = CSPI2_BASE_ADDR,
477 .end = CSPI2_BASE_ADDR + SZ_4K - 1,
478 .flags = IORESOURCE_MEM,
479 }, {
480 .start = MXC_INT_CSPI2,
481 .end = MXC_INT_CSPI2,
482 .flags = IORESOURCE_IRQ,
483 },
484};
485
486static struct resource imx_spi_2_resources[] = {
487 {
488 .start = CSPI3_BASE_ADDR,
489 .end = CSPI3_BASE_ADDR + SZ_4K - 1,
490 .flags = IORESOURCE_MEM,
491 }, {
492 .start = MXC_INT_CSPI3,
493 .end = MXC_INT_CSPI3,
494 .flags = IORESOURCE_IRQ,
495 },
496};
497
498struct platform_device imx_spi_device0 = {
499 .name = "spi_imx",
500 .id = 0,
501 .num_resources = ARRAY_SIZE(imx_spi_0_resources),
502 .resource = imx_spi_0_resources,
503};
504
505struct platform_device imx_spi_device1 = {
506 .name = "spi_imx",
507 .id = 1,
508 .num_resources = ARRAY_SIZE(imx_spi_1_resources),
509 .resource = imx_spi_1_resources,
510};
511
512struct platform_device imx_spi_device2 = {
513 .name = "spi_imx",
514 .id = 2,
515 .num_resources = ARRAY_SIZE(imx_spi_2_resources),
516 .resource = imx_spi_2_resources,
517};
518
398#ifdef CONFIG_ARCH_MX35 519#ifdef CONFIG_ARCH_MX35
399static struct resource mxc_fec_resources[] = { 520static struct resource mxc_fec_resources[] = {
400 { 521 {
401 .start = MXC_FEC_BASE_ADDR, 522 .start = MXC_FEC_BASE_ADDR,
402 .end = MXC_FEC_BASE_ADDR + 0xfff, 523 .end = MXC_FEC_BASE_ADDR + 0xfff,
403 .flags = IORESOURCE_MEM 524 .flags = IORESOURCE_MEM,
404 }, { 525 }, {
405 .start = MXC_INT_FEC, 526 .start = MXC_INT_FEC,
406 .end = MXC_INT_FEC, 527 .end = MXC_INT_FEC,
407 .flags = IORESOURCE_IRQ 528 .flags = IORESOURCE_IRQ,
408 }, 529 },
409}; 530};
410 531
@@ -426,6 +547,14 @@ static int mx3_devices_init(void)
426 if (cpu_is_mx35()) { 547 if (cpu_is_mx35()) {
427 mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; 548 mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
428 mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff; 549 mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
550 otg_resources[0].start = MX35_OTG_BASE_ADDR;
551 otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff;
552 otg_resources[1].start = MXC_INT_USBOTG;
553 otg_resources[1].end = MXC_INT_USBOTG;
554 mxc_usbh1_resources[0].start = MX35_OTG_BASE_ADDR + 0x400;
555 mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff;
556 mxc_usbh1_resources[1].start = MXC_INT_USBHS;
557 mxc_usbh1_resources[1].end = MXC_INT_USBHS;
429 } 558 }
430 559
431 return 0; 560 return 0;
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index ffd494ddd4ac..79f2be45d139 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -16,5 +16,11 @@ extern struct platform_device mxc_fec_device;
16extern struct platform_device mxcsdhc_device0; 16extern struct platform_device mxcsdhc_device0;
17extern struct platform_device mxcsdhc_device1; 17extern struct platform_device mxcsdhc_device1;
18extern struct platform_device mxc_otg_udc_device; 18extern struct platform_device mxc_otg_udc_device;
19extern struct platform_device mxc_otg_host;
20extern struct platform_device mxc_usbh1;
21extern struct platform_device mxc_usbh2;
19extern struct platform_device mxc_rnga_device; 22extern struct platform_device mxc_rnga_device;
23extern struct platform_device imx_spi_device0;
24extern struct platform_device imx_spi_device1;
25extern struct platform_device imx_spi_device2;
20 26
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 1f5fdd456cb9..ad5a1122d765 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -30,6 +30,7 @@
30 30
31#include <mach/common.h> 31#include <mach/common.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/iomux-v3.h>
33 34
34/*! 35/*!
35 * @file mm.c 36 * @file mm.c
@@ -75,6 +76,7 @@ static struct map_desc mxc_io_desc[] __initdata = {
75void __init mx31_map_io(void) 76void __init mx31_map_io(void)
76{ 77{
77 mxc_set_cpu_type(MXC_CPU_MX31); 78 mxc_set_cpu_type(MXC_CPU_MX31);
79 mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
78 80
79 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); 81 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
80} 82}
@@ -82,10 +84,22 @@ void __init mx31_map_io(void)
82void __init mx35_map_io(void) 84void __init mx35_map_io(void)
83{ 85{
84 mxc_set_cpu_type(MXC_CPU_MX35); 86 mxc_set_cpu_type(MXC_CPU_MX35);
87 mxc_iomux_v3_init(IO_ADDRESS(IOMUXC_BASE_ADDR));
88 mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
85 89
86 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); 90 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
87} 91}
88 92
93void __init mx31_init_irq(void)
94{
95 mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
96}
97
98void __init mx35_init_irq(void)
99{
100 mx31_init_irq();
101}
102
89#ifdef CONFIG_CACHE_L2X0 103#ifdef CONFIG_CACHE_L2X0
90static int mxc_init_l2x0(void) 104static int mxc_init_l2x0(void)
91{ 105{
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
index 30e2767a78ae..0497c152be18 100644
--- a/arch/arm/mach-mx3/mx31ads.c
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -517,7 +517,7 @@ static void __init mx31ads_map_io(void)
517 517
518static void __init mx31ads_init_irq(void) 518static void __init mx31ads_init_irq(void)
519{ 519{
520 mxc_init_irq(); 520 mx31_init_irq();
521 mx31ads_init_expio(); 521 mx31ads_init_expio();
522} 522}
523 523
diff --git a/arch/arm/mach-mx3/mx31lilly.c b/arch/arm/mach-mx3/mx31lilly.c
index 6ab2f163cb95..423025150f6f 100644
--- a/arch/arm/mach-mx3/mx31lilly.c
+++ b/arch/arm/mach-mx3/mx31lilly.c
@@ -148,7 +148,7 @@ MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
148 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 148 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
149 .boot_params = PHYS_OFFSET + 0x100, 149 .boot_params = PHYS_OFFSET + 0x100,
150 .map_io = mx31_map_io, 150 .map_io = mx31_map_io,
151 .init_irq = mxc_init_irq, 151 .init_irq = mx31_init_irq,
152 .init_machine = mx31lilly_board_init, 152 .init_machine = mx31lilly_board_init,
153 .timer = &mx31lilly_timer, 153 .timer = &mx31lilly_timer,
154MACHINE_END 154MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c
index 86fe70fa3e13..a8d57decdfdb 100644
--- a/arch/arm/mach-mx3/mx31lite.c
+++ b/arch/arm/mach-mx3/mx31lite.c
@@ -71,12 +71,11 @@ static struct smsc911x_platform_config smsc911x_config = {
71}; 71};
72 72
73static struct resource smsc911x_resources[] = { 73static struct resource smsc911x_resources[] = {
74 [0] = { 74 {
75 .start = CS4_BASE_ADDR, 75 .start = CS4_BASE_ADDR,
76 .end = CS4_BASE_ADDR + 0x100, 76 .end = CS4_BASE_ADDR + 0x100,
77 .flags = IORESOURCE_MEM, 77 .flags = IORESOURCE_MEM,
78 }, 78 }, {
79 [1] = {
80 .start = IOMUX_TO_IRQ(MX31_PIN_SFS6), 79 .start = IOMUX_TO_IRQ(MX31_PIN_SFS6),
81 .end = IOMUX_TO_IRQ(MX31_PIN_SFS6), 80 .end = IOMUX_TO_IRQ(MX31_PIN_SFS6),
82 .flags = IORESOURCE_IRQ, 81 .flags = IORESOURCE_IRQ,
@@ -162,7 +161,7 @@ MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT")
162 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 161 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
163 .boot_params = PHYS_OFFSET + 0x100, 162 .boot_params = PHYS_OFFSET + 0x100,
164 .map_io = mx31lite_map_io, 163 .map_io = mx31lite_map_io,
165 .init_irq = mxc_init_irq, 164 .init_irq = mx31_init_irq,
166 .init_machine = mxc_board_init, 165 .init_machine = mxc_board_init,
167 .timer = &mx31lite_timer, 166 .timer = &mx31lite_timer,
168MACHINE_END 167MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c
index b48581e7dedd..5592cdb8d0ad 100644
--- a/arch/arm/mach-mx3/mx31moboard-devboard.c
+++ b/arch/arm/mach-mx3/mx31moboard-devboard.c
@@ -16,7 +16,6 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19#include <linux/fsl_devices.h>
20#include <linux/gpio.h> 19#include <linux/gpio.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <linux/interrupt.h> 21#include <linux/interrupt.h>
@@ -40,18 +39,6 @@ static unsigned int devboard_pins[] = {
40 MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, 39 MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
41 MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, 40 MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
42 MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, 41 MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
43 /* USB OTG */
44 MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
45 MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
46 MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
47 MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
48 MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
49 MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
50 MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
51 MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
52 MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
53 MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
54 MX31_PIN_USB_OC__GPIO1_30,
55}; 42};
56 43
57static struct imxuart_platform_data uart_pdata = { 44static struct imxuart_platform_data uart_pdata = {
@@ -111,33 +98,6 @@ static struct imxmmc_platform_data sdhc2_pdata = {
111 .exit = devboard_sdhc2_exit, 98 .exit = devboard_sdhc2_exit,
112}; 99};
113 100
114static struct fsl_usb2_platform_data usb_pdata = {
115 .operating_mode = FSL_USB2_DR_DEVICE,
116 .phy_mode = FSL_USB2_PHY_ULPI,
117};
118
119#define OTG_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)
120#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
121
122static void devboard_usbotg_init(void)
123{
124 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, OTG_PAD_CFG);
125 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, OTG_PAD_CFG);
126 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, OTG_PAD_CFG);
127 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, OTG_PAD_CFG);
128 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, OTG_PAD_CFG);
129 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, OTG_PAD_CFG);
130 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, OTG_PAD_CFG);
131 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, OTG_PAD_CFG);
132 mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, OTG_PAD_CFG);
133 mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, OTG_PAD_CFG);
134 mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, OTG_PAD_CFG);
135 mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, OTG_PAD_CFG);
136
137 gpio_request(OTG_EN_B, "usb-udc-en");
138 gpio_direction_output(OTG_EN_B, 0);
139}
140
141/* 101/*
142 * system init for baseboard usage. Will be called by mx31moboard init. 102 * system init for baseboard usage. Will be called by mx31moboard init.
143 */ 103 */
@@ -151,7 +111,4 @@ void __init mx31moboard_devboard_init(void)
151 mxc_register_device(&mxc_uart_device1, &uart_pdata); 111 mxc_register_device(&mxc_uart_device1, &uart_pdata);
152 112
153 mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); 113 mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
154
155 devboard_usbotg_init();
156 mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
157} 114}
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
index 901fb0166c0e..2bfaffb344f0 100644
--- a/arch/arm/mach-mx3/mx31moboard-marxbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -16,7 +16,6 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19#include <linux/fsl_devices.h>
20#include <linux/gpio.h> 19#include <linux/gpio.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <linux/interrupt.h> 21#include <linux/interrupt.h>
@@ -48,18 +47,8 @@ static unsigned int marxbot_pins[] = {
48 MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, 47 MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
49 MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, 48 MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
50 MX31_PIN_TXD2__GPIO1_28, 49 MX31_PIN_TXD2__GPIO1_28,
51 /* USB OTG */ 50 /* dsPIC resets */
52 MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, 51 MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22,
53 MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
54 MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
55 MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
56 MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
57 MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
58 MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
59 MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
60 MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
61 MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
62 MX31_PIN_USB_OC__GPIO1_30,
63}; 52};
64 53
65#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) 54#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
@@ -115,31 +104,20 @@ static struct imxmmc_platform_data sdhc2_pdata = {
115 .exit = marxbot_sdhc2_exit, 104 .exit = marxbot_sdhc2_exit,
116}; 105};
117 106
118static struct fsl_usb2_platform_data usb_pdata = { 107#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_STXD5)
119 .operating_mode = FSL_USB2_DR_DEVICE, 108#define DSPICS_RST_B IOMUX_TO_GPIO(MX31_PIN_SRXD5)
120 .phy_mode = FSL_USB2_PHY_ULPI,
121};
122
123#define OTG_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)
124#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
125 109
126static void marxbot_usbotg_init(void) 110static void dspics_resets_init(void)
127{ 111{
128 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, OTG_PAD_CFG); 112 if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
129 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, OTG_PAD_CFG); 113 gpio_direction_output(TRSLAT_RST_B, 1);
130 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, OTG_PAD_CFG); 114 gpio_export(TRSLAT_RST_B, false);
131 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, OTG_PAD_CFG); 115 }
132 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, OTG_PAD_CFG); 116
133 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, OTG_PAD_CFG); 117 if (!gpio_request(DSPICS_RST_B, "dspics-rst")) {
134 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, OTG_PAD_CFG); 118 gpio_direction_output(DSPICS_RST_B, 1);
135 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, OTG_PAD_CFG); 119 gpio_export(DSPICS_RST_B, false);
136 mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, OTG_PAD_CFG); 120 }
137 mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, OTG_PAD_CFG);
138 mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, OTG_PAD_CFG);
139 mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, OTG_PAD_CFG);
140
141 gpio_request(OTG_EN_B, "usb-udc-en");
142 gpio_direction_output(OTG_EN_B, 0);
143} 121}
144 122
145/* 123/*
@@ -152,8 +130,7 @@ void __init mx31moboard_marxbot_init(void)
152 mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins), 130 mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
153 "marxbot"); 131 "marxbot");
154 132
155 mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); 133 dspics_resets_init();
156 134
157 marxbot_usbotg_init(); 135 mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
158 mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
159} 136}
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c
index 2a2da4739ecf..9243de54041a 100644
--- a/arch/arm/mach-mx3/mx31moboard.c
+++ b/arch/arm/mach-mx3/mx31moboard.c
@@ -16,9 +16,12 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18 18
19#include <linux/delay.h>
20#include <linux/fsl_devices.h>
19#include <linux/gpio.h> 21#include <linux/gpio.h>
20#include <linux/init.h> 22#include <linux/init.h>
21#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/leds.h>
22#include <linux/memory.h> 25#include <linux/memory.h>
23#include <linux/mtd/physmap.h> 26#include <linux/mtd/physmap.h>
24#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
@@ -36,6 +39,7 @@
36#include <mach/iomux-mx3.h> 39#include <mach/iomux-mx3.h>
37#include <mach/i2c.h> 40#include <mach/i2c.h>
38#include <mach/mmc.h> 41#include <mach/mmc.h>
42#include <mach/mx31.h>
39 43
40#include "devices.h" 44#include "devices.h"
41 45
@@ -55,6 +59,26 @@ static unsigned int moboard_pins[] = {
55 MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0, 59 MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0,
56 MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD, 60 MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD,
57 MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27, 61 MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
62 /* USB reset */
63 MX31_PIN_GPIO1_0__GPIO1_0,
64 /* USB OTG */
65 MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
66 MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
67 MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
68 MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
69 MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
70 MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
71 MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
72 MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
73 MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
74 MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
75 MX31_PIN_USB_OC__GPIO1_30,
76 /* LEDs */
77 MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
78 MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
79 /* SEL */
80 MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
81 MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
58}; 82};
59 83
60static struct physmap_flash_data mx31moboard_flash_data = { 84static struct physmap_flash_data mx31moboard_flash_data = {
@@ -142,8 +166,109 @@ static struct imxmmc_platform_data sdhc1_pdata = {
142 .exit = moboard_sdhc1_exit, 166 .exit = moboard_sdhc1_exit,
143}; 167};
144 168
169/*
170 * this pin is dedicated for all mx31moboard systems, so we do it here
171 */
172#define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
173
174static void usb_xcvr_reset(void)
175{
176 gpio_request(USB_RESET_B, "usb-reset");
177 gpio_direction_output(USB_RESET_B, 0);
178 mdelay(1);
179 gpio_set_value(USB_RESET_B, 1);
180}
181
182#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
183 PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
184
185#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
186
187static void moboard_usbotg_init(void)
188{
189 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
190 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
191 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
192 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
193 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
194 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
195 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
196 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
197 mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
198 mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
199 mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
200 mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
201
202 gpio_request(OTG_EN_B, "usb-udc-en");
203 gpio_direction_output(OTG_EN_B, 0);
204}
205
206static struct fsl_usb2_platform_data usb_pdata = {
207 .operating_mode = FSL_USB2_DR_DEVICE,
208 .phy_mode = FSL_USB2_PHY_ULPI,
209};
210
211static struct gpio_led mx31moboard_leds[] = {
212 {
213 .name = "coreboard-led-0:red:running",
214 .default_trigger = "heartbeat",
215 .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0),
216 }, {
217 .name = "coreboard-led-1:red",
218 .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0),
219 }, {
220 .name = "coreboard-led-2:red",
221 .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0),
222 }, {
223 .name = "coreboard-led-3:red",
224 .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
225 },
226};
227
228static struct gpio_led_platform_data mx31moboard_led_pdata = {
229 .num_leds = ARRAY_SIZE(mx31moboard_leds),
230 .leds = mx31moboard_leds,
231};
232
233static struct platform_device mx31moboard_leds_device = {
234 .name = "leds-gpio",
235 .id = -1,
236 .dev = {
237 .platform_data = &mx31moboard_led_pdata,
238 },
239};
240
241#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
242#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
243#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
244#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
245
246static void mx31moboard_init_sel_gpios(void)
247{
248 if (!gpio_request(SEL0, "sel0")) {
249 gpio_direction_input(SEL0);
250 gpio_export(SEL0, true);
251 }
252
253 if (!gpio_request(SEL1, "sel1")) {
254 gpio_direction_input(SEL1);
255 gpio_export(SEL1, true);
256 }
257
258 if (!gpio_request(SEL2, "sel2")) {
259 gpio_direction_input(SEL2);
260 gpio_export(SEL2, true);
261 }
262
263 if (!gpio_request(SEL3, "sel3")) {
264 gpio_direction_input(SEL3);
265 gpio_export(SEL3, true);
266 }
267}
268
145static struct platform_device *devices[] __initdata = { 269static struct platform_device *devices[] __initdata = {
146 &mx31moboard_flash, 270 &mx31moboard_flash,
271 &mx31moboard_leds_device,
147}; 272};
148 273
149static int mx31moboard_baseboard; 274static int mx31moboard_baseboard;
@@ -162,11 +287,18 @@ static void __init mxc_board_init(void)
162 mxc_register_device(&mxc_uart_device0, &uart_pdata); 287 mxc_register_device(&mxc_uart_device0, &uart_pdata);
163 mxc_register_device(&mxc_uart_device4, &uart_pdata); 288 mxc_register_device(&mxc_uart_device4, &uart_pdata);
164 289
290 mx31moboard_init_sel_gpios();
291
165 mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata); 292 mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
166 mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata); 293 mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
167 294
168 mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata); 295 mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
169 296
297 usb_xcvr_reset();
298
299 moboard_usbotg_init();
300 mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
301
170 switch (mx31moboard_baseboard) { 302 switch (mx31moboard_baseboard) {
171 case MX31NOBOARD: 303 case MX31NOBOARD:
172 break; 304 break;
@@ -197,7 +329,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
197 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 329 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
198 .boot_params = PHYS_OFFSET + 0x100, 330 .boot_params = PHYS_OFFSET + 0x100,
199 .map_io = mx31_map_io, 331 .map_io = mx31_map_io,
200 .init_irq = mxc_init_irq, 332 .init_irq = mx31_init_irq,
201 .init_machine = mxc_board_init, 333 .init_machine = mxc_board_init,
202 .timer = &mx31moboard_timer, 334 .timer = &mx31moboard_timer,
203MACHINE_END 335MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c
index c19838d2e369..0f7a2f06bc2d 100644
--- a/arch/arm/mach-mx3/mx31pdk.c
+++ b/arch/arm/mach-mx3/mx31pdk.c
@@ -265,7 +265,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
265 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 265 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
266 .boot_params = PHYS_OFFSET + 0x100, 266 .boot_params = PHYS_OFFSET + 0x100,
267 .map_io = mx31pdk_map_io, 267 .map_io = mx31pdk_map_io,
268 .init_irq = mxc_init_irq, 268 .init_irq = mx31_init_irq,
269 .init_machine = mxc_board_init, 269 .init_machine = mxc_board_init,
270 .timer = &mx31pdk_timer, 270 .timer = &mx31pdk_timer,
271MACHINE_END 271MACHINE_END
diff --git a/arch/arm/mach-mx3/mx35pdk.c b/arch/arm/mach-mx3/mx35pdk.c
index 6d15374414b9..6ff186e46ceb 100644
--- a/arch/arm/mach-mx3/mx35pdk.c
+++ b/arch/arm/mach-mx3/mx35pdk.c
@@ -98,7 +98,7 @@ MACHINE_START(MX35_3DS, "Freescale MX35PDK")
98 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 98 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
99 .boot_params = PHYS_OFFSET + 0x100, 99 .boot_params = PHYS_OFFSET + 0x100,
100 .map_io = mx35_map_io, 100 .map_io = mx35_map_io,
101 .init_irq = mxc_init_irq, 101 .init_irq = mx35_init_irq,
102 .init_machine = mxc_board_init, 102 .init_machine = mxc_board_init,
103 .timer = &mx35pdk_timer, 103 .timer = &mx35pdk_timer,
104MACHINE_END 104MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 840cfda341d0..6cbaabedf386 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -32,6 +32,7 @@
32#include <linux/spi/spi.h> 32#include <linux/spi/spi.h>
33#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/fsl_devices.h> 34#include <linux/fsl_devices.h>
35#include <linux/can/platform/sja1000.h>
35 36
36#include <media/soc_camera.h> 37#include <media/soc_camera.h>
37 38
@@ -169,6 +170,8 @@ static unsigned int pcm037_pins[] = {
169 MX31_PIN_CSI_MCLK__CSI_MCLK, 170 MX31_PIN_CSI_MCLK__CSI_MCLK,
170 MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, 171 MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
171 MX31_PIN_CSI_VSYNC__CSI_VSYNC, 172 MX31_PIN_CSI_VSYNC__CSI_VSYNC,
173 /* GPIO */
174 IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
172}; 175};
173 176
174static struct physmap_flash_data pcm037_flash_data = { 177static struct physmap_flash_data pcm037_flash_data = {
@@ -244,12 +247,11 @@ static struct imxuart_platform_data uart_pdata = {
244}; 247};
245 248
246static struct resource smsc911x_resources[] = { 249static struct resource smsc911x_resources[] = {
247 [0] = { 250 {
248 .start = CS1_BASE_ADDR + 0x300, 251 .start = CS1_BASE_ADDR + 0x300,
249 .end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1, 252 .end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
250 .flags = IORESOURCE_MEM, 253 .flags = IORESOURCE_MEM,
251 }, 254 }, {
252 [1] = {
253 .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), 255 .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
254 .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), 256 .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
255 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, 257 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
@@ -339,8 +341,7 @@ static struct i2c_board_info pcm037_i2c_devices[] = {
339 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ 341 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
340 .platform_data = &board_eeprom, 342 .platform_data = &board_eeprom,
341 }, { 343 }, {
342 I2C_BOARD_INFO("rtc-pcf8563", 0x51), 344 I2C_BOARD_INFO("pcf8563", 0x51),
343 .type = "pcf8563",
344 } 345 }
345}; 346};
346 347
@@ -515,6 +516,33 @@ static struct mx3fb_platform_data mx3fb_pdata = {
515 .num_modes = ARRAY_SIZE(fb_modedb), 516 .num_modes = ARRAY_SIZE(fb_modedb),
516}; 517};
517 518
519static struct resource pcm970_sja1000_resources[] = {
520 {
521 .start = CS5_BASE_ADDR,
522 .end = CS5_BASE_ADDR + 0x100 - 1,
523 .flags = IORESOURCE_MEM,
524 }, {
525 .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
526 .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
527 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
528 },
529};
530
531struct sja1000_platform_data pcm970_sja1000_platform_data = {
532 .clock = 16000000 / 2,
533 .ocr = 0x40 | 0x18,
534 .cdr = 0x40,
535};
536
537static struct platform_device pcm970_sja1000 = {
538 .name = "sja1000_platform",
539 .dev = {
540 .platform_data = &pcm970_sja1000_platform_data,
541 },
542 .resource = pcm970_sja1000_resources,
543 .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
544};
545
518/* 546/*
519 * Board specific initialization. 547 * Board specific initialization.
520 */ 548 */
@@ -575,6 +603,8 @@ static void __init mxc_board_init(void)
575 603
576 if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) 604 if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
577 mxc_register_device(&mx3_camera, &camera_pdata); 605 mxc_register_device(&mx3_camera, &camera_pdata);
606
607 platform_device_register(&pcm970_sja1000);
578} 608}
579 609
580static void __init pcm037_timer_init(void) 610static void __init pcm037_timer_init(void)
@@ -592,7 +622,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
592 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 622 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
593 .boot_params = PHYS_OFFSET + 0x100, 623 .boot_params = PHYS_OFFSET + 0x100,
594 .map_io = mx31_map_io, 624 .map_io = mx31_map_io,
595 .init_irq = mxc_init_irq, 625 .init_irq = mx31_init_irq,
596 .init_machine = mxc_board_init, 626 .init_machine = mxc_board_init,
597 .timer = &pcm037_timer, 627 .timer = &pcm037_timer,
598MACHINE_END 628MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm043.c b/arch/arm/mach-mx3/pcm043.c
index 8d27c324abf2..e18a224671fa 100644
--- a/arch/arm/mach-mx3/pcm043.c
+++ b/arch/arm/mach-mx3/pcm043.c
@@ -133,8 +133,7 @@ static struct i2c_board_info pcm043_i2c_devices[] = {
133 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ 133 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
134 .platform_data = &board_eeprom, 134 .platform_data = &board_eeprom,
135 }, { 135 }, {
136 I2C_BOARD_INFO("rtc-pcf8563", 0x51), 136 I2C_BOARD_INFO("pcf8563", 0x51),
137 .type = "pcf8563",
138 } 137 }
139}; 138};
140#endif 139#endif
@@ -203,7 +202,8 @@ static struct pad_desc pcm043_pads[] = {
203 MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, 202 MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
204 MX35_PAD_D3_REV__IPU_DISPB_D3_REV, 203 MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
205 MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, 204 MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
206 MX35_PAD_D3_SPL__IPU_DISPB_D3_SPL 205 /* gpio */
206 MX35_PAD_ATA_CS0__GPIO2_6,
207}; 207};
208 208
209/* 209/*
@@ -245,7 +245,7 @@ MACHINE_START(PCM043, "Phytec Phycore pcm043")
245 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 245 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
246 .boot_params = PHYS_OFFSET + 0x100, 246 .boot_params = PHYS_OFFSET + 0x100,
247 .map_io = mx35_map_io, 247 .map_io = mx35_map_io,
248 .init_irq = mxc_init_irq, 248 .init_irq = mx35_init_irq,
249 .init_machine = mxc_board_init, 249 .init_machine = mxc_board_init,
250 .timer = &pcm043_timer, 250 .timer = &pcm043_timer,
251MACHINE_END 251MACHINE_END
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c
index 82b31c4ab11f..044511f1b9a9 100644
--- a/arch/arm/mach-mx3/qong.c
+++ b/arch/arm/mach-mx3/qong.c
@@ -81,13 +81,12 @@ static inline void mxc_init_imx_uart(void)
81} 81}
82 82
83static struct resource dnet_resources[] = { 83static struct resource dnet_resources[] = {
84 [0] = { 84 {
85 .name = "dnet-memory", 85 .name = "dnet-memory",
86 .start = QONG_DNET_BASEADDR, 86 .start = QONG_DNET_BASEADDR,
87 .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, 87 .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
88 .flags = IORESOURCE_MEM, 88 .flags = IORESOURCE_MEM,
89 }, 89 }, {
90 [1] = {
91 .start = QONG_FPGA_IRQ, 90 .start = QONG_FPGA_IRQ,
92 .end = QONG_FPGA_IRQ, 91 .end = QONG_FPGA_IRQ,
93 .flags = IORESOURCE_IRQ, 92 .flags = IORESOURCE_IRQ,
@@ -280,7 +279,7 @@ MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
280 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, 279 .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
281 .boot_params = PHYS_OFFSET + 0x100, 280 .boot_params = PHYS_OFFSET + 0x100,
282 .map_io = mx31_map_io, 281 .map_io = mx31_map_io,
283 .init_irq = mxc_init_irq, 282 .init_irq = mx31_init_irq,
284 .init_machine = mxc_board_init, 283 .init_machine = mxc_board_init,
285 .timer = &qong_timer, 284 .timer = &qong_timer,
286MACHINE_END 285MACHINE_END
diff --git a/arch/arm/mach-mxc91231/Kconfig b/arch/arm/mach-mxc91231/Kconfig
new file mode 100644
index 000000000000..8e5fa38ebb67
--- /dev/null
+++ b/arch/arm/mach-mxc91231/Kconfig
@@ -0,0 +1,11 @@
1if ARCH_MXC91231
2
3comment "MXC91231 platforms:"
4
5config MACH_MAGX_ZN5
6 bool "Support Motorola Zn5 GSM phone"
7 default n
8 help
9 Include support for Motorola Zn5 GSM phone.
10
11endif
diff --git a/arch/arm/mach-mxc91231/Makefile b/arch/arm/mach-mxc91231/Makefile
new file mode 100644
index 000000000000..011d5e197125
--- /dev/null
+++ b/arch/arm/mach-mxc91231/Makefile
@@ -0,0 +1,2 @@
1obj-y := mm.o clock.o devices.o system.o iomux.o
2obj-$(CONFIG_MACH_MAGX_ZN5) += magx-zn5.o
diff --git a/arch/arm/mach-mxc91231/Makefile.boot b/arch/arm/mach-mxc91231/Makefile.boot
new file mode 100644
index 000000000000..9939a19d99a1
--- /dev/null
+++ b/arch/arm/mach-mxc91231/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x90008000
2params_phys-y := 0x90000100
3initrd_phys-y := 0x90800000
diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c
new file mode 100644
index 000000000000..ecfa37fef8ad
--- /dev/null
+++ b/arch/arm/mach-mxc91231/clock.c
@@ -0,0 +1,642 @@
1#include <linux/clk.h>
2#include <linux/kernel.h>
3#include <linux/init.h>
4#include <linux/io.h>
5
6#include <mach/clock.h>
7#include <mach/hardware.h>
8#include <mach/common.h>
9
10#include <asm/clkdev.h>
11#include <asm/bug.h>
12#include <asm/div64.h>
13
14#include "crm_regs.h"
15
16#define CRM_SMALL_DIVIDER(base, name) \
17 crm_small_divider(base, \
18 base ## _ ## name ## _OFFSET, \
19 base ## _ ## name ## _MASK)
20#define CRM_1DIVIDER(base, name) \
21 crm_divider(base, \
22 base ## _ ## name ## _OFFSET, \
23 base ## _ ## name ## _MASK, 1)
24#define CRM_16DIVIDER(base, name) \
25 crm_divider(base, \
26 base ## _ ## name ## _OFFSET, \
27 base ## _ ## name ## _MASK, 16)
28
29static u32 crm_small_divider(void __iomem *reg, u8 offset, u32 mask)
30{
31 static const u32 crm_small_dividers[] = {
32 2, 3, 4, 5, 6, 8, 10, 12
33 };
34 u8 idx;
35
36 idx = (__raw_readl(reg) & mask) >> offset;
37 if (idx > 7)
38 return 1;
39
40 return crm_small_dividers[idx];
41}
42
43static u32 crm_divider(void __iomem *reg, u8 offset, u32 mask, u32 z)
44{
45 u32 div;
46 div = (__raw_readl(reg) & mask) >> offset;
47 return div ? div : z;
48}
49
50static int _clk_1bit_enable(struct clk *clk)
51{
52 u32 reg;
53
54 reg = __raw_readl(clk->enable_reg);
55 reg |= 1 << clk->enable_shift;
56 __raw_writel(reg, clk->enable_reg);
57
58 return 0;
59}
60
61static void _clk_1bit_disable(struct clk *clk)
62{
63 u32 reg;
64
65 reg = __raw_readl(clk->enable_reg);
66 reg &= ~(1 << clk->enable_shift);
67 __raw_writel(reg, clk->enable_reg);
68}
69
70static int _clk_3bit_enable(struct clk *clk)
71{
72 u32 reg;
73
74 reg = __raw_readl(clk->enable_reg);
75 reg |= 0x7 << clk->enable_shift;
76 __raw_writel(reg, clk->enable_reg);
77
78 return 0;
79}
80
81static void _clk_3bit_disable(struct clk *clk)
82{
83 u32 reg;
84
85 reg = __raw_readl(clk->enable_reg);
86 reg &= ~(0x7 << clk->enable_shift);
87 __raw_writel(reg, clk->enable_reg);
88}
89
90static unsigned long ckih_rate;
91
92static unsigned long clk_ckih_get_rate(struct clk *clk)
93{
94 return ckih_rate;
95}
96
97static struct clk ckih_clk = {
98 .get_rate = clk_ckih_get_rate,
99};
100
101static unsigned long clk_ckih_x2_get_rate(struct clk *clk)
102{
103 return 2 * clk_get_rate(clk->parent);
104}
105
106static struct clk ckih_x2_clk = {
107 .parent = &ckih_clk,
108 .get_rate = clk_ckih_x2_get_rate,
109};
110
111static unsigned long clk_ckil_get_rate(struct clk *clk)
112{
113 return CKIL_CLK_FREQ;
114}
115
116static struct clk ckil_clk = {
117 .get_rate = clk_ckil_get_rate,
118};
119
120/* plls stuff */
121static struct clk mcu_pll_clk;
122static struct clk dsp_pll_clk;
123static struct clk usb_pll_clk;
124
125static struct clk *pll_clk(u8 sel)
126{
127 switch (sel) {
128 case 0:
129 return &mcu_pll_clk;
130 case 1:
131 return &dsp_pll_clk;
132 case 2:
133 return &usb_pll_clk;
134 }
135 BUG();
136}
137
138static void __iomem *pll_base(struct clk *clk)
139{
140 if (clk == &mcu_pll_clk)
141 return MXC_PLL0_BASE;
142 else if (clk == &dsp_pll_clk)
143 return MXC_PLL1_BASE;
144 else if (clk == &usb_pll_clk)
145 return MXC_PLL2_BASE;
146 BUG();
147}
148
149static unsigned long clk_pll_get_rate(struct clk *clk)
150{
151 const void __iomem *pllbase;
152 unsigned long dp_op, dp_mfd, dp_mfn, pll_hfsm, ref_clk, mfi;
153 long mfn, mfn_abs, mfd, pdf;
154 s64 temp;
155 pllbase = pll_base(clk);
156
157 pll_hfsm = __raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_HFSM;
158 if (pll_hfsm == 0) {
159 dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
160 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
161 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
162 } else {
163 dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
164 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
165 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
166 }
167
168 pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
169 mfi = (dp_op >> MXC_PLL_DP_OP_MFI_OFFSET) & MXC_PLL_DP_OP_PDF_MASK;
170 mfi = (mfi <= 5) ? 5 : mfi;
171 mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
172 mfn = dp_mfn & MXC_PLL_DP_MFN_MASK;
173 mfn = (mfn <= 0x4000000) ? mfn : (mfn - 0x10000000);
174
175 if (mfn < 0)
176 mfn_abs = -mfn;
177 else
178 mfn_abs = mfn;
179
180/* XXX: actually this asumes that ckih is fed to pll, but spec says
181 * that ckih_x2 is also possible. need to check this out.
182 */
183 ref_clk = clk_get_rate(&ckih_clk);
184
185 ref_clk *= 2;
186 ref_clk /= pdf + 1;
187
188 temp = (u64) ref_clk * mfn_abs;
189 do_div(temp, mfd);
190 if (mfn < 0)
191 temp = -temp;
192 temp += ref_clk * mfi;
193
194 return temp;
195}
196
197static int clk_pll_enable(struct clk *clk)
198{
199 void __iomem *ctl;
200 u32 reg;
201
202 ctl = pll_base(clk);
203 reg = __raw_readl(ctl);
204 reg |= (MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN);
205 __raw_writel(reg, ctl);
206 do {
207 reg = __raw_readl(ctl);
208 } while ((reg & MXC_PLL_DP_CTL_LRF) != MXC_PLL_DP_CTL_LRF);
209 return 0;
210}
211
212static void clk_pll_disable(struct clk *clk)
213{
214 void __iomem *ctl;
215 u32 reg;
216
217 ctl = pll_base(clk);
218 reg = __raw_readl(ctl);
219 reg &= ~(MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN);
220 __raw_writel(reg, ctl);
221}
222
223static struct clk mcu_pll_clk = {
224 .parent = &ckih_clk,
225 .get_rate = clk_pll_get_rate,
226 .enable = clk_pll_enable,
227 .disable = clk_pll_disable,
228};
229
230static struct clk dsp_pll_clk = {
231 .parent = &ckih_clk,
232 .get_rate = clk_pll_get_rate,
233 .enable = clk_pll_enable,
234 .disable = clk_pll_disable,
235};
236
237static struct clk usb_pll_clk = {
238 .parent = &ckih_clk,
239 .get_rate = clk_pll_get_rate,
240 .enable = clk_pll_enable,
241 .disable = clk_pll_disable,
242};
243/* plls stuff end */
244
245/* ap_ref_clk stuff */
246static struct clk ap_ref_clk;
247
248static unsigned long clk_ap_ref_get_rate(struct clk *clk)
249{
250 u32 ascsr, acsr;
251 u8 ap_pat_ref_div_2, ap_isel, acs, ads;
252
253 ascsr = __raw_readl(MXC_CRMAP_ASCSR);
254 acsr = __raw_readl(MXC_CRMAP_ACSR);
255
256 /* 0 for ckih, 1 for ckih*2 */
257 ap_isel = ascsr & MXC_CRMAP_ASCSR_APISEL;
258 /* reg divider */
259 ap_pat_ref_div_2 = (ascsr >> MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET) & 0x1;
260 /* undocumented, 1 for disabling divider */
261 ads = (acsr >> MXC_CRMAP_ACSR_ADS_OFFSET) & 0x1;
262 /* 0 for pat_ref, 1 for divider out */
263 acs = acsr & MXC_CRMAP_ACSR_ACS;
264
265 if (acs & !ads)
266 /* use divided clock */
267 return clk_get_rate(clk->parent) / (ap_pat_ref_div_2 ? 2 : 1);
268
269 return clk_get_rate(clk->parent) * (ap_isel ? 2 : 1);
270}
271
272static struct clk ap_ref_clk = {
273 .parent = &ckih_clk,
274 .get_rate = clk_ap_ref_get_rate,
275};
276/* ap_ref_clk stuff end */
277
278/* ap_pre_dfs_clk stuff */
279static struct clk ap_pre_dfs_clk;
280
281static unsigned long clk_ap_pre_dfs_get_rate(struct clk *clk)
282{
283 u32 acsr, ascsr;
284
285 acsr = __raw_readl(MXC_CRMAP_ACSR);
286 ascsr = __raw_readl(MXC_CRMAP_ASCSR);
287
288 if (acsr & MXC_CRMAP_ACSR_ACS) {
289 u8 sel;
290 sel = (ascsr & MXC_CRMAP_ASCSR_APSEL_MASK) >>
291 MXC_CRMAP_ASCSR_APSEL_OFFSET;
292 return clk_get_rate(pll_clk(sel)) /
293 CRM_SMALL_DIVIDER(MXC_CRMAP_ACDR, ARMDIV);
294 }
295 return clk_get_rate(&ap_ref_clk);
296}
297
298static struct clk ap_pre_dfs_clk = {
299 .get_rate = clk_ap_pre_dfs_get_rate,
300};
301/* ap_pre_dfs_clk stuff end */
302
303/* usb_clk stuff */
304static struct clk usb_clk;
305
306static struct clk *clk_usb_parent(struct clk *clk)
307{
308 u32 acsr, ascsr;
309
310 acsr = __raw_readl(MXC_CRMAP_ACSR);
311 ascsr = __raw_readl(MXC_CRMAP_ASCSR);
312
313 if (acsr & MXC_CRMAP_ACSR_ACS) {
314 u8 sel;
315 sel = (ascsr & MXC_CRMAP_ASCSR_USBSEL_MASK) >>
316 MXC_CRMAP_ASCSR_USBSEL_OFFSET;
317 return pll_clk(sel);
318 }
319 return &ap_ref_clk;
320}
321
322static unsigned long clk_usb_get_rate(struct clk *clk)
323{
324 return clk_get_rate(clk->parent) /
325 CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, USBDIV);
326}
327
328static struct clk usb_clk = {
329 .enable_reg = MXC_CRMAP_ACDER2,
330 .enable_shift = MXC_CRMAP_ACDER2_USBEN_OFFSET,
331 .get_rate = clk_usb_get_rate,
332 .enable = _clk_1bit_enable,
333 .disable = _clk_1bit_disable,
334};
335/* usb_clk stuff end */
336
337static unsigned long clk_ipg_get_rate(struct clk *clk)
338{
339 return clk_get_rate(clk->parent) / CRM_16DIVIDER(MXC_CRMAP_ACDR, IPDIV);
340}
341
342static unsigned long clk_ahb_get_rate(struct clk *clk)
343{
344 return clk_get_rate(clk->parent) /
345 CRM_16DIVIDER(MXC_CRMAP_ACDR, AHBDIV);
346}
347
348static struct clk ipg_clk = {
349 .parent = &ap_pre_dfs_clk,
350 .get_rate = clk_ipg_get_rate,
351};
352
353static struct clk ahb_clk = {
354 .parent = &ap_pre_dfs_clk,
355 .get_rate = clk_ahb_get_rate,
356};
357
358/* perclk_clk stuff */
359static struct clk perclk_clk;
360
361static unsigned long clk_perclk_get_rate(struct clk *clk)
362{
363 u32 acder2;
364
365 acder2 = __raw_readl(MXC_CRMAP_ACDER2);
366 if (acder2 & MXC_CRMAP_ACDER2_BAUD_ISEL_MASK)
367 return 2 * clk_get_rate(clk->parent);
368
369 return clk_get_rate(clk->parent);
370}
371
372static struct clk perclk_clk = {
373 .parent = &ckih_clk,
374 .get_rate = clk_perclk_get_rate,
375};
376/* perclk_clk stuff end */
377
378/* uart_clk stuff */
379static struct clk uart_clk[];
380
381static unsigned long clk_uart_get_rate(struct clk *clk)
382{
383 u32 div;
384
385 switch (clk->id) {
386 case 0:
387 case 1:
388 div = CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, BAUDDIV);
389 break;
390 case 2:
391 div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRA, UART3DIV);
392 break;
393 default:
394 BUG();
395 }
396 return clk_get_rate(clk->parent) / div;
397}
398
399static struct clk uart_clk[] = {
400 {
401 .id = 0,
402 .parent = &perclk_clk,
403 .enable_reg = MXC_CRMAP_APRA,
404 .enable_shift = MXC_CRMAP_APRA_UART1EN_OFFSET,
405 .get_rate = clk_uart_get_rate,
406 .enable = _clk_1bit_enable,
407 .disable = _clk_1bit_disable,
408 }, {
409 .id = 1,
410 .parent = &perclk_clk,
411 .enable_reg = MXC_CRMAP_APRA,
412 .enable_shift = MXC_CRMAP_APRA_UART2EN_OFFSET,
413 .get_rate = clk_uart_get_rate,
414 .enable = _clk_1bit_enable,
415 .disable = _clk_1bit_disable,
416 }, {
417 .id = 2,
418 .parent = &perclk_clk,
419 .enable_reg = MXC_CRMAP_APRA,
420 .enable_shift = MXC_CRMAP_APRA_UART3EN_OFFSET,
421 .get_rate = clk_uart_get_rate,
422 .enable = _clk_1bit_enable,
423 .disable = _clk_1bit_disable,
424 },
425};
426/* uart_clk stuff end */
427
428/* sdhc_clk stuff */
429static struct clk nfc_clk;
430
431static unsigned long clk_nfc_get_rate(struct clk *clk)
432{
433 return clk_get_rate(clk->parent) /
434 CRM_1DIVIDER(MXC_CRMAP_ACDER2, NFCDIV);
435}
436
437static struct clk nfc_clk = {
438 .parent = &ahb_clk,
439 .enable_reg = MXC_CRMAP_ACDER2,
440 .enable_shift = MXC_CRMAP_ACDER2_NFCEN_OFFSET,
441 .get_rate = clk_nfc_get_rate,
442 .enable = _clk_1bit_enable,
443 .disable = _clk_1bit_disable,
444};
445/* sdhc_clk stuff end */
446
447/* sdhc_clk stuff */
448static struct clk sdhc_clk[];
449
450static struct clk *clk_sdhc_parent(struct clk *clk)
451{
452 u32 aprb;
453 u8 sel;
454 u32 mask;
455 int offset;
456
457 aprb = __raw_readl(MXC_CRMAP_APRB);
458
459 switch (clk->id) {
460 case 0:
461 mask = MXC_CRMAP_APRB_SDHC1_ISEL_MASK;
462 offset = MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET;
463 break;
464 case 1:
465 mask = MXC_CRMAP_APRB_SDHC2_ISEL_MASK;
466 offset = MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET;
467 break;
468 default:
469 BUG();
470 }
471 sel = (aprb & mask) >> offset;
472
473 switch (sel) {
474 case 0:
475 return &ckih_clk;
476 case 1:
477 return &ckih_x2_clk;
478 }
479 return &usb_clk;
480}
481
482static unsigned long clk_sdhc_get_rate(struct clk *clk)
483{
484 u32 div;
485
486 switch (clk->id) {
487 case 0:
488 div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC1_DIV);
489 break;
490 case 1:
491 div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC2_DIV);
492 break;
493 default:
494 BUG();
495 }
496
497 return clk_get_rate(clk->parent) / div;
498}
499
500static int clk_sdhc_enable(struct clk *clk)
501{
502 u32 amlpmre1, aprb;
503
504 amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1);
505 aprb = __raw_readl(MXC_CRMAP_APRB);
506 switch (clk->id) {
507 case 0:
508 amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET);
509 aprb |= (0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET);
510 break;
511 case 1:
512 amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET);
513 aprb |= (0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET);
514 break;
515 }
516 __raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1);
517 __raw_writel(aprb, MXC_CRMAP_APRB);
518 return 0;
519}
520
521static void clk_sdhc_disable(struct clk *clk)
522{
523 u32 amlpmre1, aprb;
524
525 amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1);
526 aprb = __raw_readl(MXC_CRMAP_APRB);
527 switch (clk->id) {
528 case 0:
529 amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET);
530 aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET);
531 break;
532 case 1:
533 amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET);
534 aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET);
535 break;
536 }
537 __raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1);
538 __raw_writel(aprb, MXC_CRMAP_APRB);
539}
540
541static struct clk sdhc_clk[] = {
542 {
543 .id = 0,
544 .get_rate = clk_sdhc_get_rate,
545 .enable = clk_sdhc_enable,
546 .disable = clk_sdhc_disable,
547 }, {
548 .id = 1,
549 .get_rate = clk_sdhc_get_rate,
550 .enable = clk_sdhc_enable,
551 .disable = clk_sdhc_disable,
552 },
553};
554/* sdhc_clk stuff end */
555
556/* wdog_clk stuff */
557static struct clk wdog_clk[] = {
558 {
559 .id = 0,
560 .parent = &ipg_clk,
561 .enable_reg = MXC_CRMAP_AMLPMRD,
562 .enable_shift = MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET,
563 .enable = _clk_3bit_enable,
564 .disable = _clk_3bit_disable,
565 }, {
566 .id = 1,
567 .parent = &ipg_clk,
568 .enable_reg = MXC_CRMAP_AMLPMRD,
569 .enable_shift = MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET,
570 .enable = _clk_3bit_enable,
571 .disable = _clk_3bit_disable,
572 },
573};
574/* wdog_clk stuff end */
575
576/* gpt_clk stuff */
577static struct clk gpt_clk = {
578 .parent = &ipg_clk,
579 .enable_reg = MXC_CRMAP_AMLPMRC,
580 .enable_shift = MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET,
581 .enable = _clk_3bit_enable,
582 .disable = _clk_3bit_disable,
583};
584/* gpt_clk stuff end */
585
586/* cspi_clk stuff */
587static struct clk cspi_clk[] = {
588 {
589 .id = 0,
590 .parent = &ipg_clk,
591 .enable_reg = MXC_CRMAP_AMLPMRE2,
592 .enable_shift = MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET,
593 .enable = _clk_3bit_enable,
594 .disable = _clk_3bit_disable,
595 }, {
596 .id = 1,
597 .parent = &ipg_clk,
598 .enable_reg = MXC_CRMAP_AMLPMRE1,
599 .enable_shift = MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET,
600 .enable = _clk_3bit_enable,
601 .disable = _clk_3bit_disable,
602 },
603};
604/* cspi_clk stuff end */
605
606#define _REGISTER_CLOCK(d, n, c) \
607 { \
608 .dev_id = d, \
609 .con_id = n, \
610 .clk = &c, \
611 },
612
613static struct clk_lookup lookups[] = {
614 _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
615 _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
616 _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
617 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc_clk[0])
618 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc_clk[1])
619 _REGISTER_CLOCK("mxc-wdt.0", NULL, wdog_clk[0])
620 _REGISTER_CLOCK("spi_imx.0", NULL, cspi_clk[0])
621 _REGISTER_CLOCK("spi_imx.1", NULL, cspi_clk[1])
622};
623
624int __init mxc91231_clocks_init(unsigned long fref)
625{
626 void __iomem *gpt_base;
627 int i;
628
629 ckih_rate = fref;
630
631 usb_clk.parent = clk_usb_parent(&usb_clk);
632 sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]);
633 sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]);
634
635 for (i = 0; i < ARRAY_SIZE(lookups); i++)
636 clkdev_add(&lookups[i]);
637
638 gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR);
639 mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT);
640
641 return 0;
642}
diff --git a/arch/arm/mach-mxc91231/crm_regs.h b/arch/arm/mach-mxc91231/crm_regs.h
new file mode 100644
index 000000000000..ce4f59058189
--- /dev/null
+++ b/arch/arm/mach-mxc91231/crm_regs.h
@@ -0,0 +1,399 @@
1/*
2 * Copyright 2006 Freescale Semiconductor, Inc.
3 * Copyright 2006-2007 Motorola, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#ifndef _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
22#define _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
23
24#define CKIL_CLK_FREQ 32768
25
26#define MXC_CRM_AP_BASE MXC91231_IO_ADDRESS(MXC91231_CRM_AP_BASE_ADDR)
27#define MXC_CRM_COM_BASE MXC91231_IO_ADDRESS(MXC91231_CRM_COM_BASE_ADDR)
28#define MXC_DSM_BASE MXC91231_IO_ADDRESS(MXC91231_DSM_BASE_ADDR)
29#define MXC_PLL0_BASE MXC91231_IO_ADDRESS(MXC91231_PLL0_BASE_ADDR)
30#define MXC_PLL1_BASE MXC91231_IO_ADDRESS(MXC91231_PLL1_BASE_ADDR)
31#define MXC_PLL2_BASE MXC91231_IO_ADDRESS(MXC91231_PLL2_BASE_ADDR)
32#define MXC_CLKCTL_BASE MXC91231_IO_ADDRESS(MXC91231_CLKCTL_BASE_ADDR)
33
34/* PLL Register Offsets */
35#define MXC_PLL_DP_CTL 0x00
36#define MXC_PLL_DP_CONFIG 0x04
37#define MXC_PLL_DP_OP 0x08
38#define MXC_PLL_DP_MFD 0x0C
39#define MXC_PLL_DP_MFN 0x10
40#define MXC_PLL_DP_HFS_OP 0x1C
41#define MXC_PLL_DP_HFS_MFD 0x20
42#define MXC_PLL_DP_HFS_MFN 0x24
43
44/* PLL Register Bit definitions */
45#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
46#define MXC_PLL_DP_CTL_ADE 0x800
47#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
48#define MXC_PLL_DP_CTL_HFSM 0x80
49#define MXC_PLL_DP_CTL_PRE 0x40
50#define MXC_PLL_DP_CTL_UPEN 0x20
51#define MXC_PLL_DP_CTL_RST 0x10
52#define MXC_PLL_DP_CTL_RCP 0x8
53#define MXC_PLL_DP_CTL_PLM 0x4
54#define MXC_PLL_DP_CTL_BRM0 0x2
55#define MXC_PLL_DP_CTL_LRF 0x1
56
57#define MXC_PLL_DP_OP_MFI_OFFSET 4
58#define MXC_PLL_DP_OP_MFI_MASK 0xF
59#define MXC_PLL_DP_OP_PDF_OFFSET 0
60#define MXC_PLL_DP_OP_PDF_MASK 0xF
61
62#define MXC_PLL_DP_MFD_OFFSET 0
63#define MXC_PLL_DP_MFD_MASK 0x7FFFFFF
64
65#define MXC_PLL_DP_MFN_OFFSET 0
66#define MXC_PLL_DP_MFN_MASK 0x7FFFFFF
67
68/* CRM AP Register Offsets */
69#define MXC_CRMAP_ASCSR (MXC_CRM_AP_BASE + 0x00)
70#define MXC_CRMAP_ACDR (MXC_CRM_AP_BASE + 0x04)
71#define MXC_CRMAP_ACDER1 (MXC_CRM_AP_BASE + 0x08)
72#define MXC_CRMAP_ACDER2 (MXC_CRM_AP_BASE + 0x0C)
73#define MXC_CRMAP_ACGCR (MXC_CRM_AP_BASE + 0x10)
74#define MXC_CRMAP_ACCGCR (MXC_CRM_AP_BASE + 0x14)
75#define MXC_CRMAP_AMLPMRA (MXC_CRM_AP_BASE + 0x18)
76#define MXC_CRMAP_AMLPMRB (MXC_CRM_AP_BASE + 0x1C)
77#define MXC_CRMAP_AMLPMRC (MXC_CRM_AP_BASE + 0x20)
78#define MXC_CRMAP_AMLPMRD (MXC_CRM_AP_BASE + 0x24)
79#define MXC_CRMAP_AMLPMRE1 (MXC_CRM_AP_BASE + 0x28)
80#define MXC_CRMAP_AMLPMRE2 (MXC_CRM_AP_BASE + 0x2C)
81#define MXC_CRMAP_AMLPMRF (MXC_CRM_AP_BASE + 0x30)
82#define MXC_CRMAP_AMLPMRG (MXC_CRM_AP_BASE + 0x34)
83#define MXC_CRMAP_APGCR (MXC_CRM_AP_BASE + 0x38)
84#define MXC_CRMAP_ACSR (MXC_CRM_AP_BASE + 0x3C)
85#define MXC_CRMAP_ADCR (MXC_CRM_AP_BASE + 0x40)
86#define MXC_CRMAP_ACR (MXC_CRM_AP_BASE + 0x44)
87#define MXC_CRMAP_AMCR (MXC_CRM_AP_BASE + 0x48)
88#define MXC_CRMAP_APCR (MXC_CRM_AP_BASE + 0x4C)
89#define MXC_CRMAP_AMORA (MXC_CRM_AP_BASE + 0x50)
90#define MXC_CRMAP_AMORB (MXC_CRM_AP_BASE + 0x54)
91#define MXC_CRMAP_AGPR (MXC_CRM_AP_BASE + 0x58)
92#define MXC_CRMAP_APRA (MXC_CRM_AP_BASE + 0x5C)
93#define MXC_CRMAP_APRB (MXC_CRM_AP_BASE + 0x60)
94#define MXC_CRMAP_APOR (MXC_CRM_AP_BASE + 0x64)
95#define MXC_CRMAP_ADFMR (MXC_CRM_AP_BASE + 0x68)
96
97/* CRM AP Register Bit definitions */
98#define MXC_CRMAP_ASCSR_CRS 0x10000
99#define MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET 15
100#define MXC_CRMAP_ASCSR_AP_PATREF_DIV2 0x8000
101#define MXC_CRMAP_ASCSR_USBSEL_OFFSET 13
102#define MXC_CRMAP_ASCSR_USBSEL_MASK (0x3 << 13)
103#define MXC_CRMAP_ASCSR_CSISEL_OFFSET 11
104#define MXC_CRMAP_ASCSR_CSISEL_MASK (0x3 << 11)
105#define MXC_CRMAP_ASCSR_SSI2SEL_OFFSET 7
106#define MXC_CRMAP_ASCSR_SSI2SEL_MASK (0x3 << 7)
107#define MXC_CRMAP_ASCSR_SSI1SEL_OFFSET 5
108#define MXC_CRMAP_ASCSR_SSI1SEL_MASK (0x3 << 5)
109#define MXC_CRMAP_ASCSR_APSEL_OFFSET 3
110#define MXC_CRMAP_ASCSR_APSEL_MASK (0x3 << 3)
111#define MXC_CRMAP_ASCSR_AP_PATDIV1_OFFSET 2
112#define MXC_CRMAP_ASCSR_AP_PATREF_DIV1 0x4
113#define MXC_CRMAP_ASCSR_APISEL 0x1
114
115#define MXC_CRMAP_ACDR_ARMDIV_OFFSET 8
116#define MXC_CRMAP_ACDR_ARMDIV_MASK (0xF << 8)
117#define MXC_CRMAP_ACDR_AHBDIV_OFFSET 4
118#define MXC_CRMAP_ACDR_AHBDIV_MASK (0xF << 4)
119#define MXC_CRMAP_ACDR_IPDIV_OFFSET 0
120#define MXC_CRMAP_ACDR_IPDIV_MASK 0xF
121
122#define MXC_CRMAP_ACDER1_CSIEN_OFFSET 30
123#define MXC_CRMAP_ACDER1_CSIDIV_OFFSET 24
124#define MXC_CRMAP_ACDER1_CSIDIV_MASK (0x3F << 24)
125#define MXC_CRMAP_ACDER1_SSI2EN_OFFSET 14
126#define MXC_CRMAP_ACDER1_SSI2DIV_OFFSET 8
127#define MXC_CRMAP_ACDER1_SSI2DIV_MASK (0x3F << 8)
128#define MXC_CRMAP_ACDER1_SSI1EN_OFFSET 6
129#define MXC_CRMAP_ACDER1_SSI1DIV_OFFSET 0
130#define MXC_CRMAP_ACDER1_SSI1DIV_MASK 0x3F
131
132#define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_OFFSET 24
133#define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_MASK (0x7 << 24)
134#define MXC_CRMAP_ACDER2_NFCEN_OFFSET 20
135#define MXC_CRMAP_ACDER2_NFCDIV_OFFSET 16
136#define MXC_CRMAP_ACDER2_NFCDIV_MASK (0xF << 16)
137#define MXC_CRMAP_ACDER2_USBEN_OFFSET 12
138#define MXC_CRMAP_ACDER2_USBDIV_OFFSET 8
139#define MXC_CRMAP_ACDER2_USBDIV_MASK (0xF << 8)
140#define MXC_CRMAP_ACDER2_BAUD_ISEL_OFFSET 5
141#define MXC_CRMAP_ACDER2_BAUD_ISEL_MASK (0x3 << 5)
142#define MXC_CRMAP_ACDER2_BAUDDIV_OFFSET 0
143#define MXC_CRMAP_ACDER2_BAUDDIV_MASK 0xF
144
145#define MXC_CRMAP_AMLPMRA_MLPMA7_OFFSET 22
146#define MXC_CRMAP_AMLPMRA_MLPMA7_MASK (0x7 << 22)
147#define MXC_CRMAP_AMLPMRA_MLPMA6_OFFSET 19
148#define MXC_CRMAP_AMLPMRA_MLPMA6_MASK (0x7 << 19)
149#define MXC_CRMAP_AMLPMRA_MLPMA4_OFFSET 12
150#define MXC_CRMAP_AMLPMRA_MLPMA4_MASK (0x7 << 12)
151#define MXC_CRMAP_AMLPMRA_MLPMA3_OFFSET 9
152#define MXC_CRMAP_AMLPMRA_MLPMA3_MASK (0x7 << 9)
153#define MXC_CRMAP_AMLPMRA_MLPMA2_OFFSET 6
154#define MXC_CRMAP_AMLPMRA_MLPMA2_MASK (0x7 << 6)
155#define MXC_CRMAP_AMLPMRA_MLPMA1_OFFSET 3
156#define MXC_CRMAP_AMLPMRA_MLPMA1_MASK (0x7 << 3)
157
158#define MXC_CRMAP_AMLPMRB_MLPMB0_OFFSET 0
159#define MXC_CRMAP_AMLPMRB_MLPMB0_MASK 0x7
160
161#define MXC_CRMAP_AMLPMRC_MLPMC9_OFFSET 28
162#define MXC_CRMAP_AMLPMRC_MLPMC9_MASK (0x7 << 28)
163#define MXC_CRMAP_AMLPMRC_MLPMC7_OFFSET 22
164#define MXC_CRMAP_AMLPMRC_MLPMC7_MASK (0x7 << 22)
165#define MXC_CRMAP_AMLPMRC_MLPMC5_OFFSET 16
166#define MXC_CRMAP_AMLPMRC_MLPMC5_MASK (0x7 << 16)
167#define MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET 12
168#define MXC_CRMAP_AMLPMRC_MLPMC4_MASK (0x7 << 12)
169#define MXC_CRMAP_AMLPMRC_MLPMC3_OFFSET 9
170#define MXC_CRMAP_AMLPMRC_MLPMC3_MASK (0x7 << 9)
171#define MXC_CRMAP_AMLPMRC_MLPMC2_OFFSET 6
172#define MXC_CRMAP_AMLPMRC_MLPMC2_MASK (0x7 << 6)
173#define MXC_CRMAP_AMLPMRC_MLPMC1_OFFSET 3
174#define MXC_CRMAP_AMLPMRC_MLPMC1_MASK (0x7 << 3)
175#define MXC_CRMAP_AMLPMRC_MLPMC0_OFFSET 0
176#define MXC_CRMAP_AMLPMRC_MLPMC0_MASK 0x7
177
178#define MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET 22
179#define MXC_CRMAP_AMLPMRD_MLPMD7_MASK (0x7 << 22)
180#define MXC_CRMAP_AMLPMRD_MLPMD4_OFFSET 12
181#define MXC_CRMAP_AMLPMRD_MLPMD4_MASK (0x7 << 12)
182#define MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET 9
183#define MXC_CRMAP_AMLPMRD_MLPMD3_MASK (0x7 << 9)
184#define MXC_CRMAP_AMLPMRD_MLPMD2_OFFSET 6
185#define MXC_CRMAP_AMLPMRD_MLPMD2_MASK (0x7 << 6)
186#define MXC_CRMAP_AMLPMRD_MLPMD0_OFFSET 0
187#define MXC_CRMAP_AMLPMRD_MLPMD0_MASK 0x7
188
189#define MXC_CRMAP_AMLPMRE1_MLPME9_OFFSET 28
190#define MXC_CRMAP_AMLPMRE1_MLPME9_MASK (0x7 << 28)
191#define MXC_CRMAP_AMLPMRE1_MLPME8_OFFSET 25
192#define MXC_CRMAP_AMLPMRE1_MLPME8_MASK (0x7 << 25)
193#define MXC_CRMAP_AMLPMRE1_MLPME7_OFFSET 22
194#define MXC_CRMAP_AMLPMRE1_MLPME7_MASK (0x7 << 22)
195#define MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET 19
196#define MXC_CRMAP_AMLPMRE1_MLPME6_MASK (0x7 << 19)
197#define MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET 16
198#define MXC_CRMAP_AMLPMRE1_MLPME5_MASK (0x7 << 16)
199#define MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET 12
200#define MXC_CRMAP_AMLPMRE1_MLPME4_MASK (0x7 << 12)
201#define MXC_CRMAP_AMLPMRE1_MLPME3_OFFSET 9
202#define MXC_CRMAP_AMLPMRE1_MLPME3_MASK (0x7 << 9)
203#define MXC_CRMAP_AMLPMRE1_MLPME2_OFFSET 6
204#define MXC_CRMAP_AMLPMRE1_MLPME2_MASK (0x7 << 6)
205#define MXC_CRMAP_AMLPMRE1_MLPME1_OFFSET 3
206#define MXC_CRMAP_AMLPMRE1_MLPME1_MASK (0x7 << 3)
207#define MXC_CRMAP_AMLPMRE1_MLPME0_OFFSET 0
208#define MXC_CRMAP_AMLPMRE1_MLPME0_MASK 0x7
209
210#define MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET 0
211#define MXC_CRMAP_AMLPMRE2_MLPME0_MASK 0x7
212
213#define MXC_CRMAP_AMLPMRF_MLPMF6_OFFSET 19
214#define MXC_CRMAP_AMLPMRF_MLPMF6_MASK (0x7 << 19)
215#define MXC_CRMAP_AMLPMRF_MLPMF5_OFFSET 16
216#define MXC_CRMAP_AMLPMRF_MLPMF5_MASK (0x7 << 16)
217#define MXC_CRMAP_AMLPMRF_MLPMF3_OFFSET 9
218#define MXC_CRMAP_AMLPMRF_MLPMF3_MASK (0x7 << 9)
219#define MXC_CRMAP_AMLPMRF_MLPMF2_OFFSET 6
220#define MXC_CRMAP_AMLPMRF_MLPMF2_MASK (0x7 << 6)
221#define MXC_CRMAP_AMLPMRF_MLPMF1_OFFSET 3
222#define MXC_CRMAP_AMLPMRF_MLPMF1_MASK (0x7 << 3)
223#define MXC_CRMAP_AMLPMRF_MLPMF0_OFFSET 0
224#define MXC_CRMAP_AMLPMRF_MLPMF0_MASK (0x7 << 0)
225
226#define MXC_CRMAP_AMLPMRG_MLPMG9_OFFSET 28
227#define MXC_CRMAP_AMLPMRG_MLPMG9_MASK (0x7 << 28)
228#define MXC_CRMAP_AMLPMRG_MLPMG7_OFFSET 22
229#define MXC_CRMAP_AMLPMRG_MLPMG7_MASK (0x7 << 22)
230#define MXC_CRMAP_AMLPMRG_MLPMG6_OFFSET 19
231#define MXC_CRMAP_AMLPMRG_MLPMG6_MASK (0x7 << 19)
232#define MXC_CRMAP_AMLPMRG_MLPMG5_OFFSET 16
233#define MXC_CRMAP_AMLPMRG_MLPMG5_MASK (0x7 << 16)
234#define MXC_CRMAP_AMLPMRG_MLPMG4_OFFSET 12
235#define MXC_CRMAP_AMLPMRG_MLPMG4_MASK (0x7 << 12)
236#define MXC_CRMAP_AMLPMRG_MLPMG3_OFFSET 9
237#define MXC_CRMAP_AMLPMRG_MLPMG3_MASK (0x7 << 9)
238#define MXC_CRMAP_AMLPMRG_MLPMG2_OFFSET 6
239#define MXC_CRMAP_AMLPMRG_MLPMG2_MASK (0x7 << 6)
240#define MXC_CRMAP_AMLPMRG_MLPMG1_OFFSET 3
241#define MXC_CRMAP_AMLPMRG_MLPMG1_MASK (0x7 << 3)
242#define MXC_CRMAP_AMLPMRG_MLPMG0_OFFSET 0
243#define MXC_CRMAP_AMLPMRG_MLPMG0_MASK 0x7
244
245#define MXC_CRMAP_AGPR_IPUPAD_OFFSET 20
246#define MXC_CRMAP_AGPR_IPUPAD_MASK (0x7 << 20)
247
248#define MXC_CRMAP_APRA_EL1TEN_OFFSET 29
249#define MXC_CRMAP_APRA_SIMEN_OFFSET 24
250#define MXC_CRMAP_APRA_UART3DIV_OFFSET 17
251#define MXC_CRMAP_APRA_UART3DIV_MASK (0xF << 17)
252#define MXC_CRMAP_APRA_UART3EN_OFFSET 16
253#define MXC_CRMAP_APRA_SAHARA_DIV2_CLKEN_OFFSET 14
254#define MXC_CRMAP_APRA_MQSPIEN_OFFSET 13
255#define MXC_CRMAP_APRA_UART2EN_OFFSET 8
256#define MXC_CRMAP_APRA_UART1EN_OFFSET 0
257
258#define MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET 13
259#define MXC_CRMAP_APRB_SDHC2_ISEL_MASK (0x7 << 13)
260#define MXC_CRMAP_APRB_SDHC2_DIV_OFFSET 9
261#define MXC_CRMAP_APRB_SDHC2_DIV_MASK (0xF << 9)
262#define MXC_CRMAP_APRB_SDHC2EN_OFFSET 8
263#define MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET 5
264#define MXC_CRMAP_APRB_SDHC1_ISEL_MASK (0x7 << 5)
265#define MXC_CRMAP_APRB_SDHC1_DIV_OFFSET 1
266#define MXC_CRMAP_APRB_SDHC1_DIV_MASK (0xF << 1)
267#define MXC_CRMAP_APRB_SDHC1EN_OFFSET 0
268
269#define MXC_CRMAP_ACSR_ADS_OFFSET 8
270#define MXC_CRMAP_ACSR_ADS (0x1 << 8)
271#define MXC_CRMAP_ACSR_ACS 0x1
272
273#define MXC_CRMAP_ADCR_LFDF_0 (0x0 << 8)
274#define MXC_CRMAP_ADCR_LFDF_2 (0x1 << 8)
275#define MXC_CRMAP_ADCR_LFDF_4 (0x2 << 8)
276#define MXC_CRMAP_ADCR_LFDF_8 (0x3 << 8)
277#define MXC_CRMAP_ADCR_LFDF_OFFSET 8
278#define MXC_CRMAP_ADCR_LFDF_MASK (0x3 << 8)
279#define MXC_CRMAP_ADCR_ALT_PLL 0x80
280#define MXC_CRMAP_ADCR_DFS_DIVEN 0x20
281#define MXC_CRMAP_ADCR_DIV_BYP 0x2
282#define MXC_CRMAP_ADCR_VSTAT 0x8
283#define MXC_CRMAP_ADCR_TSTAT 0x10
284#define MXC_CRMAP_ADCR_DVFS_VCTRL 0x10
285#define MXC_CRMAP_ADCR_CLK_ON 0x40
286
287#define MXC_CRMAP_ADFMR_FC_OFFSET 16
288#define MXC_CRMAP_ADFMR_FC_MASK (0x1F << 16)
289#define MXC_CRMAP_ADFMR_MF_OFFSET 1
290#define MXC_CRMAP_ADFMR_MF_MASK (0x3FF << 1)
291#define MXC_CRMAP_ADFMR_DFM_CLK_READY 0x1
292#define MXC_CRMAP_ADFMR_DFM_PWR_DOWN 0x8000
293
294#define MXC_CRMAP_ACR_CKOHS_HIGH (1 << 18)
295#define MXC_CRMAP_ACR_CKOS_HIGH (1 << 16)
296#define MXC_CRMAP_ACR_CKOHS_MASK (0x7 << 12)
297#define MXC_CRMAP_ACR_CKOHD (1 << 11)
298#define MXC_CRMAP_ACR_CKOHDIV_MASK (0xF << 8)
299#define MXC_CRMAP_ACR_CKOHDIV_OFFSET 8
300#define MXC_CRMAP_ACR_CKOD (1 << 7)
301#define MXC_CRMAP_ACR_CKOS_MASK (0x7 << 4)
302
303/* AP Warm reset */
304#define MXC_CRMAP_AMCR_SW_AP (1 << 14)
305
306/* Bit definitions of ACGCR in CRM_AP for tree level clock gating */
307#define MXC_CRMAP_ACGCR_ACG0_STOP_WAIT 0x00000001
308#define MXC_CRMAP_ACGCR_ACG0_STOP 0x00000003
309#define MXC_CRMAP_ACGCR_ACG0_RUN 0x00000007
310#define MXC_CRMAP_ACGCR_ACG0_DISABLED 0x00000000
311
312#define MXC_CRMAP_ACGCR_ACG1_STOP_WAIT 0x00000008
313#define MXC_CRMAP_ACGCR_ACG1_STOP 0x00000018
314#define MXC_CRMAP_ACGCR_ACG1_RUN 0x00000038
315#define MXC_CRMAP_ACGCR_ACG1_DISABLED 0x00000000
316
317#define MXC_CRMAP_ACGCR_ACG2_STOP_WAIT 0x00000040
318#define MXC_CRMAP_ACGCR_ACG2_STOP 0x000000C0
319#define MXC_CRMAP_ACGCR_ACG2_RUN 0x000001C0
320#define MXC_CRMAP_ACGCR_ACG2_DISABLED 0x00000000
321
322#define MXC_CRMAP_ACGCR_ACG3_STOP_WAIT 0x00000200
323#define MXC_CRMAP_ACGCR_ACG3_STOP 0x00000600
324#define MXC_CRMAP_ACGCR_ACG3_RUN 0x00000E00
325#define MXC_CRMAP_ACGCR_ACG3_DISABLED 0x00000000
326
327#define MXC_CRMAP_ACGCR_ACG4_STOP_WAIT 0x00001000
328#define MXC_CRMAP_ACGCR_ACG4_STOP 0x00003000
329#define MXC_CRMAP_ACGCR_ACG4_RUN 0x00007000
330#define MXC_CRMAP_ACGCR_ACG4_DISABLED 0x00000000
331
332#define MXC_CRMAP_ACGCR_ACG5_STOP_WAIT 0x00010000
333#define MXC_CRMAP_ACGCR_ACG5_STOP 0x00030000
334#define MXC_CRMAP_ACGCR_ACG5_RUN 0x00070000
335#define MXC_CRMAP_ACGCR_ACG5_DISABLED 0x00000000
336
337#define MXC_CRMAP_ACGCR_ACG6_STOP_WAIT 0x00080000
338#define MXC_CRMAP_ACGCR_ACG6_STOP 0x00180000
339#define MXC_CRMAP_ACGCR_ACG6_RUN 0x00380000
340#define MXC_CRMAP_ACGCR_ACG6_DISABLED 0x00000000
341
342#define NUM_GATE_CTRL 6
343
344/* CRM COM Register Offsets */
345#define MXC_CRMCOM_CSCR (MXC_CRM_COM_BASE + 0x0C)
346#define MXC_CRMCOM_CCCR (MXC_CRM_COM_BASE + 0x10)
347
348/* CRM COM Bit Definitions */
349#define MXC_CRMCOM_CSCR_PPD1 0x08000000
350#define MXC_CRMCOM_CSCR_CKOHSEL (1 << 18)
351#define MXC_CRMCOM_CSCR_CKOSEL (1 << 17)
352#define MXC_CRMCOM_CCCR_CC_DIV_OFFSET 8
353#define MXC_CRMCOM_CCCR_CC_DIV_MASK (0x1F << 8)
354#define MXC_CRMCOM_CCCR_CC_SEL_OFFSET 0
355#define MXC_CRMCOM_CCCR_CC_SEL_MASK 0x3
356
357/* DSM Register Offsets */
358#define MXC_DSM_SLEEP_TIME (MXC_DSM_BASE + 0x0c)
359#define MXC_DSM_CONTROL0 (MXC_DSM_BASE + 0x20)
360#define MXC_DSM_CONTROL1 (MXC_DSM_BASE + 0x24)
361#define MXC_DSM_CTREN (MXC_DSM_BASE + 0x28)
362#define MXC_DSM_WARM_PER (MXC_DSM_BASE + 0x40)
363#define MXC_DSM_LOCK_PER (MXC_DSM_BASE + 0x44)
364#define MXC_DSM_MGPER (MXC_DSM_BASE + 0x4c)
365#define MXC_DSM_CRM_CONTROL (MXC_DSM_BASE + 0x50)
366
367/* Bit definitions of various registers in DSM */
368#define MXC_DSM_CRM_CTRL_DVFS_BYP 0x00000008
369#define MXC_DSM_CRM_CTRL_DVFS_VCTRL 0x00000004
370#define MXC_DSM_CRM_CTRL_LPMD1 0x00000002
371#define MXC_DSM_CRM_CTRL_LPMD0 0x00000001
372#define MXC_DSM_CRM_CTRL_LPMD_STOP_MODE 0x00000000
373#define MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE 0x00000001
374#define MXC_DSM_CRM_CTRL_LPMD_RUN_MODE 0x00000003
375#define MXC_DSM_CONTROL0_STBY_COMMIT_EN 0x00000200
376#define MXC_DSM_CONTROL0_MSTR_EN 0x00000001
377#define MXC_DSM_CONTROL0_RESTART 0x00000010
378/* Counter Block reset */
379#define MXC_DSM_CONTROL1_CB_RST 0x00000002
380/* State Machine reset */
381#define MXC_DSM_CONTROL1_SM_RST 0x00000004
382/* Bit needed to reset counter block */
383#define MXC_CONTROL1_RST_CNT32 0x00000008
384#define MXC_DSM_CONTROL1_RST_CNT32_EN 0x00000800
385#define MXC_DSM_CONTROL1_SLEEP 0x00000100
386#define MXC_DSM_CONTROL1_WAKEUP_DISABLE 0x00004000
387#define MXC_DSM_CTREN_CNT32 0x00000001
388
389/* Magic Fix enable bit */
390#define MXC_DSM_MGPER_EN_MGFX 0x80000000
391#define MXC_DSM_MGPER_PER_MASK 0x000003FF
392#define MXC_DSM_MGPER_PER(n) (MXC_DSM_MGPER_PER_MASK & n)
393
394/* Address offsets of the CLKCTL registers */
395#define MXC_CLKCTL_GP_CTRL (MXC_CLKCTL_BASE + 0x00)
396#define MXC_CLKCTL_GP_SER (MXC_CLKCTL_BASE + 0x04)
397#define MXC_CLKCTL_GP_CER (MXC_CLKCTL_BASE + 0x08)
398
399#endif /* _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_ */
diff --git a/arch/arm/mach-mxc91231/devices.c b/arch/arm/mach-mxc91231/devices.c
new file mode 100644
index 000000000000..353bd977b393
--- /dev/null
+++ b/arch/arm/mach-mxc91231/devices.c
@@ -0,0 +1,251 @@
1/*
2 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/serial.h>
23#include <linux/gpio.h>
24#include <mach/hardware.h>
25#include <mach/irqs.h>
26#include <mach/imx-uart.h>
27
28static struct resource uart0[] = {
29 {
30 .start = MXC91231_UART1_BASE_ADDR,
31 .end = MXC91231_UART1_BASE_ADDR + 0x0B5,
32 .flags = IORESOURCE_MEM,
33 }, {
34 .start = MXC91231_INT_UART1_RX,
35 .end = MXC91231_INT_UART1_RX,
36 .flags = IORESOURCE_IRQ,
37 }, {
38 .start = MXC91231_INT_UART1_TX,
39 .end = MXC91231_INT_UART1_TX,
40 .flags = IORESOURCE_IRQ,
41 }, {
42 .start = MXC91231_INT_UART1_MINT,
43 .end = MXC91231_INT_UART1_MINT,
44 .flags = IORESOURCE_IRQ,
45 },
46};
47
48struct platform_device mxc_uart_device0 = {
49 .name = "imx-uart",
50 .id = 0,
51 .resource = uart0,
52 .num_resources = ARRAY_SIZE(uart0),
53};
54
55static struct resource uart1[] = {
56 {
57 .start = MXC91231_UART2_BASE_ADDR,
58 .end = MXC91231_UART2_BASE_ADDR + 0x0B5,
59 .flags = IORESOURCE_MEM,
60 }, {
61 .start = MXC91231_INT_UART2_RX,
62 .end = MXC91231_INT_UART2_RX,
63 .flags = IORESOURCE_IRQ,
64 }, {
65 .start = MXC91231_INT_UART2_TX,
66 .end = MXC91231_INT_UART2_TX,
67 .flags = IORESOURCE_IRQ,
68 }, {
69 .start = MXC91231_INT_UART2_MINT,
70 .end = MXC91231_INT_UART2_MINT,
71 .flags = IORESOURCE_IRQ,
72 },
73};
74
75struct platform_device mxc_uart_device1 = {
76 .name = "imx-uart",
77 .id = 1,
78 .resource = uart1,
79 .num_resources = ARRAY_SIZE(uart1),
80};
81
82static struct resource uart2[] = {
83 {
84 .start = MXC91231_UART3_BASE_ADDR,
85 .end = MXC91231_UART3_BASE_ADDR + 0x0B5,
86 .flags = IORESOURCE_MEM,
87 }, {
88 .start = MXC91231_INT_UART3_RX,
89 .end = MXC91231_INT_UART3_RX,
90 .flags = IORESOURCE_IRQ,
91 }, {
92 .start = MXC91231_INT_UART3_TX,
93 .end = MXC91231_INT_UART3_TX,
94 .flags = IORESOURCE_IRQ,
95 }, {
96 .start = MXC91231_INT_UART3_MINT,
97 .end = MXC91231_INT_UART3_MINT,
98 .flags = IORESOURCE_IRQ,
99
100 },
101};
102
103struct platform_device mxc_uart_device2 = {
104 .name = "imx-uart",
105 .id = 2,
106 .resource = uart2,
107 .num_resources = ARRAY_SIZE(uart2),
108};
109
110/* GPIO port description */
111static struct mxc_gpio_port mxc_gpio_ports[] = {
112 [0] = {
113 .chip.label = "gpio-0",
114 .base = MXC91231_IO_ADDRESS(MXC91231_GPIO1_AP_BASE_ADDR),
115 .irq = MXC91231_INT_GPIO1,
116 .virtual_irq_start = MXC_GPIO_IRQ_START,
117 },
118 [1] = {
119 .chip.label = "gpio-1",
120 .base = MXC91231_IO_ADDRESS(MXC91231_GPIO2_AP_BASE_ADDR),
121 .irq = MXC91231_INT_GPIO2,
122 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
123 },
124 [2] = {
125 .chip.label = "gpio-2",
126 .base = MXC91231_IO_ADDRESS(MXC91231_GPIO3_AP_BASE_ADDR),
127 .irq = MXC91231_INT_GPIO3,
128 .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
129 },
130 [3] = {
131 .chip.label = "gpio-3",
132 .base = MXC91231_IO_ADDRESS(MXC91231_GPIO4_SH_BASE_ADDR),
133 .irq = MXC91231_INT_GPIO4,
134 .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
135 },
136};
137
138int __init mxc_register_gpios(void)
139{
140 return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
141}
142
143static struct resource mxc_nand_resources[] = {
144 {
145 .start = MXC91231_NFC_BASE_ADDR,
146 .end = MXC91231_NFC_BASE_ADDR + 0xfff,
147 .flags = IORESOURCE_MEM
148 }, {
149 .start = MXC91231_INT_NANDFC,
150 .end = MXC91231_INT_NANDFC,
151 .flags = IORESOURCE_IRQ
152 },
153};
154
155struct platform_device mxc_nand_device = {
156 .name = "mxc_nand",
157 .id = 0,
158 .num_resources = ARRAY_SIZE(mxc_nand_resources),
159 .resource = mxc_nand_resources,
160};
161
162static struct resource mxc_sdhc0_resources[] = {
163 {
164 .start = MXC91231_MMC_SDHC1_BASE_ADDR,
165 .end = MXC91231_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
166 .flags = IORESOURCE_MEM,
167 }, {
168 .start = MXC91231_INT_MMC_SDHC1,
169 .end = MXC91231_INT_MMC_SDHC1,
170 .flags = IORESOURCE_IRQ,
171 },
172};
173
174static struct resource mxc_sdhc1_resources[] = {
175 {
176 .start = MXC91231_MMC_SDHC2_BASE_ADDR,
177 .end = MXC91231_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
178 .flags = IORESOURCE_MEM,
179 }, {
180 .start = MXC91231_INT_MMC_SDHC2,
181 .end = MXC91231_INT_MMC_SDHC2,
182 .flags = IORESOURCE_IRQ,
183 },
184};
185
186struct platform_device mxc_sdhc_device0 = {
187 .name = "mxc-mmc",
188 .id = 0,
189 .num_resources = ARRAY_SIZE(mxc_sdhc0_resources),
190 .resource = mxc_sdhc0_resources,
191};
192
193struct platform_device mxc_sdhc_device1 = {
194 .name = "mxc-mmc",
195 .id = 1,
196 .num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
197 .resource = mxc_sdhc1_resources,
198};
199
200static struct resource mxc_cspi0_resources[] = {
201 {
202 .start = MXC91231_CSPI1_BASE_ADDR,
203 .end = MXC91231_CSPI1_BASE_ADDR + 0x20,
204 .flags = IORESOURCE_MEM,
205 }, {
206 .start = MXC91231_INT_CSPI1,
207 .end = MXC91231_INT_CSPI1,
208 .flags = IORESOURCE_IRQ,
209 },
210};
211
212struct platform_device mxc_cspi_device0 = {
213 .name = "spi_imx",
214 .id = 0,
215 .num_resources = ARRAY_SIZE(mxc_cspi0_resources),
216 .resource = mxc_cspi0_resources,
217};
218
219static struct resource mxc_cspi1_resources[] = {
220 {
221 .start = MXC91231_CSPI2_BASE_ADDR,
222 .end = MXC91231_CSPI2_BASE_ADDR + 0x20,
223 .flags = IORESOURCE_MEM,
224 }, {
225 .start = MXC91231_INT_CSPI2,
226 .end = MXC91231_INT_CSPI2,
227 .flags = IORESOURCE_IRQ,
228 },
229};
230
231struct platform_device mxc_cspi_device1 = {
232 .name = "spi_imx",
233 .id = 1,
234 .num_resources = ARRAY_SIZE(mxc_cspi1_resources),
235 .resource = mxc_cspi1_resources,
236};
237
238static struct resource mxc_wdog0_resources[] = {
239 {
240 .start = MXC91231_WDOG1_BASE_ADDR,
241 .end = MXC91231_WDOG1_BASE_ADDR + 0x10,
242 .flags = IORESOURCE_MEM,
243 },
244};
245
246struct platform_device mxc_wdog_device0 = {
247 .name = "mxc-wdt",
248 .id = 0,
249 .num_resources = ARRAY_SIZE(mxc_wdog0_resources),
250 .resource = mxc_wdog0_resources,
251};
diff --git a/arch/arm/mach-mxc91231/devices.h b/arch/arm/mach-mxc91231/devices.h
new file mode 100644
index 000000000000..72a2136ce27d
--- /dev/null
+++ b/arch/arm/mach-mxc91231/devices.h
@@ -0,0 +1,13 @@
1extern struct platform_device mxc_uart_device0;
2extern struct platform_device mxc_uart_device1;
3extern struct platform_device mxc_uart_device2;
4
5extern struct platform_device mxc_nand_device;
6
7extern struct platform_device mxc_sdhc_device0;
8extern struct platform_device mxc_sdhc_device1;
9
10extern struct platform_device mxc_cspi_device0;
11extern struct platform_device mxc_cspi_device1;
12
13extern struct platform_device mxc_wdog_device0;
diff --git a/arch/arm/mach-mxc91231/iomux.c b/arch/arm/mach-mxc91231/iomux.c
new file mode 100644
index 000000000000..405d9b19d891
--- /dev/null
+++ b/arch/arm/mach-mxc91231/iomux.c
@@ -0,0 +1,177 @@
1/*
2 * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
4 * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/spinlock.h>
23#include <linux/io.h>
24#include <linux/kernel.h>
25#include <mach/hardware.h>
26#include <mach/gpio.h>
27#include <mach/iomux-mxc91231.h>
28
29/*
30 * IOMUX register (base) addresses
31 */
32#define IOMUX_AP_BASE MXC91231_IO_ADDRESS(MXC91231_IOMUX_AP_BASE_ADDR)
33#define IOMUX_COM_BASE MXC91231_IO_ADDRESS(MXC91231_IOMUX_COM_BASE_ADDR)
34#define IOMUXSW_AP_MUX_CTL (IOMUX_AP_BASE + 0x000)
35#define IOMUXSW_SP_MUX_CTL (IOMUX_COM_BASE + 0x000)
36#define IOMUXSW_PAD_CTL (IOMUX_COM_BASE + 0x200)
37
38#define IOMUXINT_OBS1 (IOMUX_AP_BASE + 0x600)
39#define IOMUXINT_OBS2 (IOMUX_AP_BASE + 0x004)
40
41static DEFINE_SPINLOCK(gpio_mux_lock);
42
43#define NB_PORTS ((PIN_MAX + 32) / 32)
44#define PIN_GLOBAL_NUM(pin) \
45 (((pin & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT)*PIN_AP_MAX + \
46 ((pin & MUX_REG_MASK) >> MUX_REG_SHIFT)*4 + \
47 ((pin & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT))
48
49unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
50/*
51 * set the mode for a IOMUX pin.
52 */
53int mxc_iomux_mode(const unsigned int pin_mode)
54{
55 u32 side, field, l, mode, ret = 0;
56 void __iomem *reg;
57
58 side = (pin_mode & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT;
59 switch (side) {
60 case MUX_SIDE_AP:
61 reg = IOMUXSW_AP_MUX_CTL;
62 break;
63 case MUX_SIDE_SP:
64 reg = IOMUXSW_SP_MUX_CTL;
65 break;
66 default:
67 return -EINVAL;
68 }
69 reg += ((pin_mode & MUX_REG_MASK) >> MUX_REG_SHIFT) * 4;
70 field = (pin_mode & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT;
71 mode = (pin_mode & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
72
73 spin_lock(&gpio_mux_lock);
74
75 l = __raw_readl(reg);
76 l &= ~(0xff << (field * 8));
77 l |= mode << (field * 8);
78 __raw_writel(l, reg);
79
80 spin_unlock(&gpio_mux_lock);
81
82 return ret;
83}
84EXPORT_SYMBOL(mxc_iomux_mode);
85
86/*
87 * This function configures the pad value for a IOMUX pin.
88 */
89void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
90{
91 u32 padgrp, field, l;
92 void __iomem *reg;
93
94 padgrp = (pin & MUX_PADGRP_MASK) >> MUX_PADGRP_SHIFT;
95 reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
96 field = (pin + 2) % 3;
97
98 pr_debug("%s: reg offset = 0x%x, field = %d\n",
99 __func__, (pin + 2) / 3, field);
100
101 spin_lock(&gpio_mux_lock);
102
103 l = __raw_readl(reg);
104 l &= ~(0x1ff << (field * 10));
105 l |= config << (field * 10);
106 __raw_writel(l, reg);
107
108 spin_unlock(&gpio_mux_lock);
109}
110EXPORT_SYMBOL(mxc_iomux_set_pad);
111
112/*
113 * allocs a single pin:
114 * - reserves the pin so that it is not claimed by another driver
115 * - setups the iomux according to the configuration
116 */
117int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label)
118{
119 unsigned pad = PIN_GLOBAL_NUM(pin_mode);
120 if (pad >= (PIN_MAX + 1)) {
121 printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
122 pad, label ? label : "?");
123 return -EINVAL;
124 }
125
126 if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
127 printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
128 pad, label ? label : "?");
129 return -EBUSY;
130 }
131 mxc_iomux_mode(pin_mode);
132
133 return 0;
134}
135EXPORT_SYMBOL(mxc_iomux_alloc_pin);
136
137int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
138 const char *label)
139{
140 unsigned int *p = pin_list;
141 int i;
142 int ret = -EINVAL;
143
144 for (i = 0; i < count; i++) {
145 ret = mxc_iomux_alloc_pin(*p, label);
146 if (ret)
147 goto setup_error;
148 p++;
149 }
150 return 0;
151
152setup_error:
153 mxc_iomux_release_multiple_pins(pin_list, i);
154 return ret;
155}
156EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
157
158void mxc_iomux_release_pin(const unsigned int pin_mode)
159{
160 unsigned pad = PIN_GLOBAL_NUM(pin_mode);
161
162 if (pad < (PIN_MAX + 1))
163 clear_bit(pad, mxc_pin_alloc_map);
164}
165EXPORT_SYMBOL(mxc_iomux_release_pin);
166
167void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
168{
169 unsigned int *p = pin_list;
170 int i;
171
172 for (i = 0; i < count; i++) {
173 mxc_iomux_release_pin(*p);
174 p++;
175 }
176}
177EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
diff --git a/arch/arm/mach-mxc91231/magx-zn5.c b/arch/arm/mach-mxc91231/magx-zn5.c
new file mode 100644
index 000000000000..7dbe4ca12efd
--- /dev/null
+++ b/arch/arm/mach-mxc91231/magx-zn5.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com>
3 *
4 * This file is released under the GPLv2 or later.
5 */
6
7#include <linux/irq.h>
8#include <linux/init.h>
9#include <linux/device.h>
10
11#include <asm/mach-types.h>
12#include <asm/mach/time.h>
13#include <asm/mach/arch.h>
14
15#include <mach/common.h>
16#include <mach/hardware.h>
17#include <mach/iomux-mxc91231.h>
18#include <mach/mmc.h>
19#include <mach/imx-uart.h>
20
21#include "devices.h"
22
23static struct imxuart_platform_data uart_pdata = {
24};
25
26static struct imxmmc_platform_data sdhc_pdata = {
27};
28
29static void __init zn5_init(void)
30{
31 pm_power_off = mxc91231_power_off;
32
33 mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_DAT_VP__RXD2, "uart2-rx");
34 mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_SE0_VM__TXD2, "uart2-tx");
35
36 mxc_register_device(&mxc_uart_device1, &uart_pdata);
37 mxc_register_device(&mxc_uart_device0, &uart_pdata);
38
39 mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata);
40
41 mxc_register_device(&mxc_wdog_device0, NULL);
42
43 return;
44}
45
46static void __init zn5_timer_init(void)
47{
48 mxc91231_clocks_init(26000000); /* 26mhz ckih */
49}
50
51struct sys_timer zn5_timer = {
52 .init = zn5_timer_init,
53};
54
55MACHINE_START(MAGX_ZN5, "Motorola Zn5")
56 .phys_io = MXC91231_AIPS1_BASE_ADDR,
57 .io_pg_offst = ((MXC91231_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
58 .boot_params = PHYS_OFFSET + 0x100,
59 .map_io = mxc91231_map_io,
60 .init_irq = mxc91231_init_irq,
61 .timer = &zn5_timer,
62 .init_machine = zn5_init,
63MACHINE_END
diff --git a/arch/arm/mach-mxc91231/mm.c b/arch/arm/mach-mxc91231/mm.c
new file mode 100644
index 000000000000..6becda3ff331
--- /dev/null
+++ b/arch/arm/mach-mxc91231/mm.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (C) 1999,2000 Arm Limited
3 * Copyright (C) 2000 Deep Blue Solutions Ltd
4 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
5 * Copyright 2004-2005 Freescale Semiconductor, Inc. All Rights Reserved.
6 * - add MXC specific definitions
7 * Copyright 2006 Motorola, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <linux/mm.h>
26#include <linux/init.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29#include <asm/pgtable.h>
30#include <asm/mach/map.h>
31
32/*
33 * This structure defines the MXC memory map.
34 */
35static struct map_desc mxc_io_desc[] __initdata = {
36 {
37 .virtual = MXC91231_L2CC_BASE_ADDR_VIRT,
38 .pfn = __phys_to_pfn(MXC91231_L2CC_BASE_ADDR),
39 .length = MXC91231_L2CC_SIZE,
40 .type = MT_DEVICE,
41 }, {
42 .virtual = MXC91231_X_MEMC_BASE_ADDR_VIRT,
43 .pfn = __phys_to_pfn(MXC91231_X_MEMC_BASE_ADDR),
44 .length = MXC91231_X_MEMC_SIZE,
45 .type = MT_DEVICE,
46 }, {
47 .virtual = MXC91231_ROMP_BASE_ADDR_VIRT,
48 .pfn = __phys_to_pfn(MXC91231_ROMP_BASE_ADDR),
49 .length = MXC91231_ROMP_SIZE,
50 .type = MT_DEVICE,
51 }, {
52 .virtual = MXC91231_AVIC_BASE_ADDR_VIRT,
53 .pfn = __phys_to_pfn(MXC91231_AVIC_BASE_ADDR),
54 .length = MXC91231_AVIC_SIZE,
55 .type = MT_DEVICE,
56 }, {
57 .virtual = MXC91231_AIPS1_BASE_ADDR_VIRT,
58 .pfn = __phys_to_pfn(MXC91231_AIPS1_BASE_ADDR),
59 .length = MXC91231_AIPS1_SIZE,
60 .type = MT_DEVICE,
61 }, {
62 .virtual = MXC91231_SPBA0_BASE_ADDR_VIRT,
63 .pfn = __phys_to_pfn(MXC91231_SPBA0_BASE_ADDR),
64 .length = MXC91231_SPBA0_SIZE,
65 .type = MT_DEVICE,
66 }, {
67 .virtual = MXC91231_SPBA1_BASE_ADDR_VIRT,
68 .pfn = __phys_to_pfn(MXC91231_SPBA1_BASE_ADDR),
69 .length = MXC91231_SPBA1_SIZE,
70 .type = MT_DEVICE,
71 }, {
72 .virtual = MXC91231_AIPS2_BASE_ADDR_VIRT,
73 .pfn = __phys_to_pfn(MXC91231_AIPS2_BASE_ADDR),
74 .length = MXC91231_AIPS2_SIZE,
75 .type = MT_DEVICE,
76 },
77};
78
79/*
80 * This function initializes the memory map. It is called during the
81 * system startup to create static physical to virtual memory map for
82 * the IO modules.
83 */
84void __init mxc91231_map_io(void)
85{
86 mxc_set_cpu_type(MXC_CPU_MXC91231);
87
88 iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
89}
90
91void __init mxc91231_init_irq(void)
92{
93 mxc_init_irq(MXC91231_IO_ADDRESS(MXC91231_AVIC_BASE_ADDR));
94}
diff --git a/arch/arm/mach-mxc91231/system.c b/arch/arm/mach-mxc91231/system.c
new file mode 100644
index 000000000000..736f7efd874a
--- /dev/null
+++ b/arch/arm/mach-mxc91231/system.c
@@ -0,0 +1,51 @@
1/*
2 * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com>
3 *
4 * This file is released under the GPLv2 or later.
5 */
6
7#include <linux/delay.h>
8#include <linux/io.h>
9
10#include <asm/proc-fns.h>
11#include <mach/hardware.h>
12
13#include "crm_regs.h"
14
15#define WDOG_WCR MXC91231_IO_ADDRESS(MXC91231_WDOG1_BASE_ADDR)
16#define WDOG_WCR_OUT_ENABLE (1 << 6)
17#define WDOG_WCR_ASSERT (1 << 5)
18
19void mxc91231_power_off(void)
20{
21 u16 wcr;
22
23 wcr = __raw_readw(WDOG_WCR);
24 wcr |= WDOG_WCR_OUT_ENABLE;
25 wcr &= ~WDOG_WCR_ASSERT;
26 __raw_writew(wcr, WDOG_WCR);
27}
28
29void mxc91231_arch_reset(char mode, const char *cmd)
30{
31 u32 amcr;
32
33 /* Reset the AP using CRM */
34 amcr = __raw_readl(MXC_CRMAP_AMCR);
35 amcr &= ~MXC_CRMAP_AMCR_SW_AP;
36 __raw_writel(amcr, MXC_CRMAP_AMCR);
37
38 mdelay(10);
39 cpu_reset(0);
40}
41
42void mxc91231_prepare_idle(void)
43{
44 u32 crm_ctl;
45
46 /* Go to WAIT mode after WFI */
47 crm_ctl = __raw_readl(MXC_DSM_CRM_CONTROL);
48 crm_ctl &= ~(MXC_DSM_CRM_CTRL_LPMD0 | MXC_DSM_CRM_CTRL_LPMD1);
49 crm_ctl |= MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE;
50 __raw_writel(crm_ctl, MXC_DSM_CRM_CONTROL);
51}
diff --git a/arch/arm/mach-netx/include/mach/entry-macro.S b/arch/arm/mach-netx/include/mach/entry-macro.S
index a1952a0feda6..844f1f9acbdf 100644
--- a/arch/arm/mach-netx/include/mach/entry-macro.S
+++ b/arch/arm/mach-netx/include/mach/entry-macro.S
@@ -24,15 +24,13 @@
24 .endm 24 .endm
25 25
26 .macro get_irqnr_preamble, base, tmp 26 .macro get_irqnr_preamble, base, tmp
27 ldr \base, =io_p2v(0x001ff000)
27 .endm 28 .endm
28 29
29 .macro arch_ret_to_user, tmp1, tmp2 30 .macro arch_ret_to_user, tmp1, tmp2
30 .endm 31 .endm
31 32
32 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 33 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
33 mov \base, #io_p2v(0x00100000)
34 add \base, \base, #0x000ff000
35
36 ldr \irqstat, [\base, #0] 34 ldr \irqstat, [\base, #0]
37 clz \irqnr, \irqstat 35 clz \irqnr, \irqstat
38 rsb \irqnr, \irqnr, #31 36 rsb \irqnr, \irqnr, #31
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
new file mode 100644
index 000000000000..2a02b49c40f0
--- /dev/null
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -0,0 +1,21 @@
1if ARCH_NOMADIK
2
3menu "Nomadik boards"
4
5config MACH_NOMADIK_8815NHK
6 bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
7 select NOMADIK_8815
8
9endmenu
10
11config NOMADIK_8815
12 bool
13
14
15config I2C_BITBANG_8815NHK
16 tristate "Driver for bit-bang busses found on the 8815 NHK"
17 depends on I2C && MACH_NOMADIK_8815NHK
18 select I2C_ALGOBIT
19 default y
20
21endif
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile
new file mode 100644
index 000000000000..412040982a40
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile
@@ -0,0 +1,19 @@
1#
2# Makefile for the linux kernel.
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7
8# Object file lists.
9
10obj-y += clock.o timer.o gpio.o
11
12# Cpu revision
13obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
14
15# Specific board support
16obj-$(CONFIG_MACH_NOMADIK_8815NHK) += board-nhk8815.o
17
18# Nomadik extra devices
19obj-$(CONFIG_I2C_BITBANG_8815NHK) += i2c-8815nhk.o
diff --git a/arch/arm/mach-nomadik/Makefile.boot b/arch/arm/mach-nomadik/Makefile.boot
new file mode 100644
index 000000000000..c7e75acfe6c9
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile.boot
@@ -0,0 +1,4 @@
1 zreladdr-y := 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x00800000
4
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
new file mode 100644
index 000000000000..79bdea943eb4
--- /dev/null
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -0,0 +1,111 @@
1/*
2 * linux/arch/arm/mach-nomadik/board-8815nhk.c
3 *
4 * Copyright (C) STMicroelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * NHK15 board specifc driver definition
11 */
12#include <linux/types.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/amba/bus.h>
17#include <linux/interrupt.h>
18#include <linux/gpio.h>
19#include <asm/mach-types.h>
20#include <asm/mach/arch.h>
21#include <asm/mach/irq.h>
22#include <mach/setup.h>
23#include "clock.h"
24
25#define __MEM_4K_RESOURCE(x) \
26 .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
27
28static struct amba_device uart0_device = {
29 .dev = { .init_name = "uart0" },
30 __MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
31 .irq = {IRQ_UART0, NO_IRQ},
32};
33
34static struct amba_device uart1_device = {
35 .dev = { .init_name = "uart1" },
36 __MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
37 .irq = {IRQ_UART1, NO_IRQ},
38};
39
40static struct amba_device *amba_devs[] __initdata = {
41 &uart0_device,
42 &uart1_device,
43};
44
45/* We have a fixed clock alone, by now */
46static struct clk nhk8815_clk_48 = {
47 .rate = 48*1000*1000,
48};
49
50static struct resource nhk8815_eth_resources[] = {
51 {
52 .name = "smc91x-regs",
53 .start = 0x34000000 + 0x300,
54 .end = 0x34000000 + SZ_64K - 1,
55 .flags = IORESOURCE_MEM,
56 }, {
57 .start = NOMADIK_GPIO_TO_IRQ(115),
58 .end = NOMADIK_GPIO_TO_IRQ(115),
59 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
60 }
61};
62
63static struct platform_device nhk8815_eth_device = {
64 .name = "smc91x",
65 .resource = nhk8815_eth_resources,
66 .num_resources = ARRAY_SIZE(nhk8815_eth_resources),
67};
68
69static int __init nhk8815_eth_init(void)
70{
71 int gpio_nr = 115; /* hardwired in the board */
72 int err;
73
74 err = gpio_request(gpio_nr, "eth_irq");
75 if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO);
76 if (!err) err = gpio_direction_input(gpio_nr);
77 if (err)
78 pr_err("Error %i in %s\n", err, __func__);
79 return err;
80}
81device_initcall(nhk8815_eth_init);
82
83static struct platform_device *nhk8815_platform_devices[] __initdata = {
84 &nhk8815_eth_device,
85 /* will add more devices */
86};
87
88static void __init nhk8815_platform_init(void)
89{
90 int i;
91
92 cpu8815_platform_init();
93 platform_add_devices(nhk8815_platform_devices,
94 ARRAY_SIZE(nhk8815_platform_devices));
95
96 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
97 nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name);
98 amba_device_register(amba_devs[i], &iomem_resource);
99 }
100}
101
102MACHINE_START(NOMADIK, "NHK8815")
103 /* Maintainer: ST MicroElectronics */
104 .phys_io = NOMADIK_UART0_BASE,
105 .io_pg_offst = (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc,
106 .boot_params = 0x100,
107 .map_io = cpu8815_map_io,
108 .init_irq = cpu8815_init_irq,
109 .timer = &nomadik_timer,
110 .init_machine = nhk8815_platform_init,
111MACHINE_END
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
new file mode 100644
index 000000000000..9f92502a0083
--- /dev/null
+++ b/arch/arm/mach-nomadik/clock.c
@@ -0,0 +1,45 @@
1/*
2 * linux/arch/arm/mach-nomadik/clock.c
3 *
4 * Copyright (C) 2009 Alessandro Rubini
5 */
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/errno.h>
9#include <linux/clk.h>
10#include <asm/clkdev.h>
11#include "clock.h"
12
13/*
14 * The nomadik board uses generic clocks, but the serial pl011 file
15 * calls clk_enable(), clk_disable(), clk_get_rate(), so we provide them
16 */
17unsigned long clk_get_rate(struct clk *clk)
18{
19 return clk->rate;
20}
21EXPORT_SYMBOL(clk_get_rate);
22
23/* enable and disable do nothing */
24int clk_enable(struct clk *clk)
25{
26 return 0;
27}
28EXPORT_SYMBOL(clk_enable);
29
30void clk_disable(struct clk *clk)
31{
32}
33EXPORT_SYMBOL(clk_disable);
34
35/* Create a clock structure with the given name */
36int nmdk_clk_create(struct clk *clk, const char *dev_id)
37{
38 struct clk_lookup *clkdev;
39
40 clkdev = clkdev_alloc(clk, NULL, dev_id);
41 if (!clkdev)
42 return -ENOMEM;
43 clkdev_add(clkdev);
44 return 0;
45}
diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h
new file mode 100644
index 000000000000..235faec7f627
--- /dev/null
+++ b/arch/arm/mach-nomadik/clock.h
@@ -0,0 +1,14 @@
1
2/*
3 * linux/arch/arm/mach-nomadik/clock.h
4 *
5 * Copyright (C) 2009 Alessandro Rubini
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11struct clk {
12 unsigned long rate;
13};
14extern int nmdk_clk_create(struct clk *clk, const char *dev_id);
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
new file mode 100644
index 000000000000..f93c59634191
--- /dev/null
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright STMicroelectronics, 2007.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <linux/types.h>
20#include <linux/init.h>
21#include <linux/device.h>
22#include <linux/amba/bus.h>
23#include <linux/gpio.h>
24
25#include <mach/hardware.h>
26#include <mach/irqs.h>
27#include <asm/mach/map.h>
28#include <asm/hardware/vic.h>
29
30#include <asm/cacheflush.h>
31#include <asm/hardware/cache-l2x0.h>
32
33/* The 8815 has 4 GPIO blocks, let's register them immediately */
34static struct nmk_gpio_platform_data cpu8815_gpio[] = {
35 {
36 .name = "GPIO-0-31",
37 .first_gpio = 0,
38 .first_irq = NOMADIK_GPIO_TO_IRQ(0),
39 .parent_irq = IRQ_GPIO0,
40 }, {
41 .name = "GPIO-32-63",
42 .first_gpio = 32,
43 .first_irq = NOMADIK_GPIO_TO_IRQ(32),
44 .parent_irq = IRQ_GPIO1,
45 }, {
46 .name = "GPIO-64-95",
47 .first_gpio = 64,
48 .first_irq = NOMADIK_GPIO_TO_IRQ(64),
49 .parent_irq = IRQ_GPIO2,
50 }, {
51 .name = "GPIO-96-127", /* 124..127 not routed to pin */
52 .first_gpio = 96,
53 .first_irq = NOMADIK_GPIO_TO_IRQ(96),
54 .parent_irq = IRQ_GPIO3,
55 }
56};
57
58#define __MEM_4K_RESOURCE(x) \
59 .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
60
61static struct amba_device cpu8815_amba_gpio[] = {
62 {
63 .dev = {
64 .init_name = "gpio0",
65 .platform_data = cpu8815_gpio + 0,
66 },
67 __MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE),
68 }, {
69 .dev = {
70 .init_name = "gpio1",
71 .platform_data = cpu8815_gpio + 1,
72 },
73 __MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE),
74 }, {
75 .dev = {
76 .init_name = "gpio2",
77 .platform_data = cpu8815_gpio + 2,
78 },
79 __MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE),
80 }, {
81 .dev = {
82 .init_name = "gpio3",
83 .platform_data = cpu8815_gpio + 3,
84 },
85 __MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE),
86 },
87};
88
89static struct amba_device *amba_devs[] __initdata = {
90 cpu8815_amba_gpio + 0,
91 cpu8815_amba_gpio + 1,
92 cpu8815_amba_gpio + 2,
93 cpu8815_amba_gpio + 3,
94};
95
96static int __init cpu8815_init(void)
97{
98 int i;
99
100 for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
101 amba_device_register(amba_devs[i], &iomem_resource);
102 return 0;
103}
104arch_initcall(cpu8815_init);
105
106/* All SoC devices live in the same area (see hardware.h) */
107static struct map_desc nomadik_io_desc[] __initdata = {
108 {
109 .virtual = NOMADIK_IO_VIRTUAL,
110 .pfn = __phys_to_pfn(NOMADIK_IO_PHYSICAL),
111 .length = NOMADIK_IO_SIZE,
112 .type = MT_DEVICE,
113 }
114 /* static ram and secured ram may be added later */
115};
116
117void __init cpu8815_map_io(void)
118{
119 iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc));
120}
121
122void __init cpu8815_init_irq(void)
123{
124 /* This modified VIC cell has two register blocks, at 0 and 0x20 */
125 vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0);
126 vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);
127}
128
129/*
130 * This function is called from the board init ("init_machine").
131 */
132 void __init cpu8815_platform_init(void)
133{
134#ifdef CONFIG_CACHE_L2X0
135 /* At full speed latency must be >=2, so 0x249 in low bits */
136 l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff);
137#endif
138 return;
139}
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
new file mode 100644
index 000000000000..9a09b2791e03
--- /dev/null
+++ b/arch/arm/mach-nomadik/gpio.c
@@ -0,0 +1,396 @@
1/*
2 * Generic GPIO driver for logic cells found in the Nomadik SoC
3 *
4 * Copyright (C) 2008,2009 STMicroelectronics
5 * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
6 * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/amba/bus.h>
17#include <linux/io.h>
18#include <linux/gpio.h>
19#include <linux/spinlock.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22
23#include <mach/hardware.h>
24#include <mach/gpio.h>
25
26/*
27 * The GPIO module in the Nomadik family of Systems-on-Chip is an
28 * AMBA device, managing 32 pins and alternate functions. The logic block
29 * is currently only used in the Nomadik.
30 *
31 * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
32 */
33
34#define NMK_GPIO_PER_CHIP 32
35struct nmk_gpio_chip {
36 struct gpio_chip chip;
37 void __iomem *addr;
38 unsigned int parent_irq;
39 spinlock_t *lock;
40 /* Keep track of configured edges */
41 u32 edge_rising;
42 u32 edge_falling;
43};
44
45/* Mode functions */
46int nmk_gpio_set_mode(int gpio, int gpio_mode)
47{
48 struct nmk_gpio_chip *nmk_chip;
49 unsigned long flags;
50 u32 afunc, bfunc, bit;
51
52 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
53 if (!nmk_chip)
54 return -EINVAL;
55
56 bit = 1 << (gpio - nmk_chip->chip.base);
57
58 spin_lock_irqsave(&nmk_chip->lock, flags);
59 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
60 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
61 if (gpio_mode & NMK_GPIO_ALT_A)
62 afunc |= bit;
63 if (gpio_mode & NMK_GPIO_ALT_B)
64 bfunc |= bit;
65 writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
66 writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
67 spin_unlock_irqrestore(&nmk_chip->lock, flags);
68
69 return 0;
70}
71EXPORT_SYMBOL(nmk_gpio_set_mode);
72
73int nmk_gpio_get_mode(int gpio)
74{
75 struct nmk_gpio_chip *nmk_chip;
76 u32 afunc, bfunc, bit;
77
78 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
79 if (!nmk_chip)
80 return -EINVAL;
81
82 bit = 1 << (gpio - nmk_chip->chip.base);
83
84 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
85 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
86
87 return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
88}
89EXPORT_SYMBOL(nmk_gpio_get_mode);
90
91
92/* IRQ functions */
93static inline int nmk_gpio_get_bitmask(int gpio)
94{
95 return 1 << (gpio % 32);
96}
97
98static void nmk_gpio_irq_ack(unsigned int irq)
99{
100 int gpio;
101 struct nmk_gpio_chip *nmk_chip;
102
103 gpio = NOMADIK_IRQ_TO_GPIO(irq);
104 nmk_chip = get_irq_chip_data(irq);
105 if (!nmk_chip)
106 return;
107 writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
108}
109
110static void nmk_gpio_irq_mask(unsigned int irq)
111{
112 int gpio;
113 struct nmk_gpio_chip *nmk_chip;
114 unsigned long flags;
115 u32 bitmask, reg;
116
117 gpio = NOMADIK_IRQ_TO_GPIO(irq);
118 nmk_chip = get_irq_chip_data(irq);
119 bitmask = nmk_gpio_get_bitmask(gpio);
120 if (!nmk_chip)
121 return;
122
123 /* we must individually clear the two edges */
124 spin_lock_irqsave(&nmk_chip->lock, flags);
125 if (nmk_chip->edge_rising & bitmask) {
126 reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
127 reg &= ~bitmask;
128 writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
129 }
130 if (nmk_chip->edge_falling & bitmask) {
131 reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
132 reg &= ~bitmask;
133 writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
134 }
135 spin_unlock_irqrestore(&nmk_chip->lock, flags);
136};
137
138static void nmk_gpio_irq_unmask(unsigned int irq)
139{
140 int gpio;
141 struct nmk_gpio_chip *nmk_chip;
142 unsigned long flags;
143 u32 bitmask, reg;
144
145 gpio = NOMADIK_IRQ_TO_GPIO(irq);
146 nmk_chip = get_irq_chip_data(irq);
147 bitmask = nmk_gpio_get_bitmask(gpio);
148 if (!nmk_chip)
149 return;
150
151 /* we must individually set the two edges */
152 spin_lock_irqsave(&nmk_chip->lock, flags);
153 if (nmk_chip->edge_rising & bitmask) {
154 reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
155 reg |= bitmask;
156 writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
157 }
158 if (nmk_chip->edge_falling & bitmask) {
159 reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
160 reg |= bitmask;
161 writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
162 }
163 spin_unlock_irqrestore(&nmk_chip->lock, flags);
164}
165
166static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
167{
168 int gpio;
169 struct nmk_gpio_chip *nmk_chip;
170 unsigned long flags;
171 u32 bitmask;
172
173 gpio = NOMADIK_IRQ_TO_GPIO(irq);
174 nmk_chip = get_irq_chip_data(irq);
175 bitmask = nmk_gpio_get_bitmask(gpio);
176 if (!nmk_chip)
177 return -EINVAL;
178
179 if (type & IRQ_TYPE_LEVEL_HIGH)
180 return -EINVAL;
181 if (type & IRQ_TYPE_LEVEL_LOW)
182 return -EINVAL;
183
184 spin_lock_irqsave(&nmk_chip->lock, flags);
185
186 nmk_chip->edge_rising &= ~bitmask;
187 if (type & IRQ_TYPE_EDGE_RISING)
188 nmk_chip->edge_rising |= bitmask;
189 writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC);
190
191 nmk_chip->edge_falling &= ~bitmask;
192 if (type & IRQ_TYPE_EDGE_FALLING)
193 nmk_chip->edge_falling |= bitmask;
194 writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC);
195
196 spin_unlock_irqrestore(&nmk_chip->lock, flags);
197
198 nmk_gpio_irq_unmask(irq);
199
200 return 0;
201}
202
203static struct irq_chip nmk_gpio_irq_chip = {
204 .name = "Nomadik-GPIO",
205 .ack = nmk_gpio_irq_ack,
206 .mask = nmk_gpio_irq_mask,
207 .unmask = nmk_gpio_irq_unmask,
208 .set_type = nmk_gpio_irq_set_type,
209};
210
211static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
212{
213 struct nmk_gpio_chip *nmk_chip;
214 struct irq_chip *host_chip;
215 unsigned int gpio_irq;
216 u32 pending;
217 unsigned int first_irq;
218
219 nmk_chip = get_irq_data(irq);
220 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
221 while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
222 gpio_irq = first_irq + __ffs(pending);
223 generic_handle_irq(gpio_irq);
224 }
225 if (0) {/* don't ack parent irq, as ack == disable */
226 host_chip = get_irq_chip(irq);
227 host_chip->ack(irq);
228 }
229}
230
231static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
232{
233 unsigned int first_irq;
234 int i;
235
236 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
237 for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
238 set_irq_chip(i, &nmk_gpio_irq_chip);
239 set_irq_handler(i, handle_edge_irq);
240 set_irq_flags(i, IRQF_VALID);
241 set_irq_chip_data(i, nmk_chip);
242 }
243 set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
244 set_irq_data(nmk_chip->parent_irq, nmk_chip);
245 return 0;
246}
247
248/* I/O Functions */
249static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
250{
251 struct nmk_gpio_chip *nmk_chip =
252 container_of(chip, struct nmk_gpio_chip, chip);
253
254 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
255 return 0;
256}
257
258static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
259 int val)
260{
261 struct nmk_gpio_chip *nmk_chip =
262 container_of(chip, struct nmk_gpio_chip, chip);
263
264 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
265 return 0;
266}
267
268static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
269{
270 struct nmk_gpio_chip *nmk_chip =
271 container_of(chip, struct nmk_gpio_chip, chip);
272 u32 bit = 1 << offset;
273
274 return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
275}
276
277static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
278 int val)
279{
280 struct nmk_gpio_chip *nmk_chip =
281 container_of(chip, struct nmk_gpio_chip, chip);
282 u32 bit = 1 << offset;
283
284 if (val)
285 writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
286 else
287 writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
288}
289
290/* This structure is replicated for each GPIO block allocated at probe time */
291static struct gpio_chip nmk_gpio_template = {
292 .direction_input = nmk_gpio_make_input,
293 .get = nmk_gpio_get_input,
294 .direction_output = nmk_gpio_make_output,
295 .set = nmk_gpio_set_output,
296 .ngpio = NMK_GPIO_PER_CHIP,
297 .can_sleep = 0,
298};
299
300static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
301{
302 struct nmk_gpio_platform_data *pdata;
303 struct nmk_gpio_chip *nmk_chip;
304 struct gpio_chip *chip;
305 int ret;
306
307 pdata = dev->dev.platform_data;
308 ret = amba_request_regions(dev, pdata->name);
309 if (ret)
310 return ret;
311
312 nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
313 if (!nmk_chip) {
314 ret = -ENOMEM;
315 goto out_amba;
316 }
317 /*
318 * The virt address in nmk_chip->addr is in the nomadik register space,
319 * so we can simply convert the resource address, without remapping
320 */
321 nmk_chip->addr = io_p2v(dev->res.start);
322 nmk_chip->chip = nmk_gpio_template;
323 nmk_chip->parent_irq = pdata->parent_irq;
324
325 chip = &nmk_chip->chip;
326 chip->base = pdata->first_gpio;
327 chip->label = pdata->name;
328 chip->dev = &dev->dev;
329 chip->owner = THIS_MODULE;
330
331 ret = gpiochip_add(&nmk_chip->chip);
332 if (ret)
333 goto out_free;
334
335 amba_set_drvdata(dev, nmk_chip);
336
337 nmk_gpio_init_irq(nmk_chip);
338
339 dev_info(&dev->dev, "Bits %i-%i at address %p\n",
340 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
341 return 0;
342
343 out_free:
344 kfree(nmk_chip);
345 out_amba:
346 amba_release_regions(dev);
347 dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
348 pdata->first_gpio, pdata->first_gpio+31);
349 return ret;
350}
351
352static int nmk_gpio_remove(struct amba_device *dev)
353{
354 struct nmk_gpio_chip *nmk_chip;
355
356 nmk_chip = amba_get_drvdata(dev);
357 gpiochip_remove(&nmk_chip->chip);
358 kfree(nmk_chip);
359 amba_release_regions(dev);
360 return 0;
361}
362
363
364/* We have 0x1f080060 and 0x1f180060, accept both using the mask */
365static struct amba_id nmk_gpio_ids[] = {
366 {
367 .id = 0x1f080060,
368 .mask = 0xffefffff,
369 },
370 {0, 0},
371};
372
373static struct amba_driver nmk_gpio_driver = {
374 .drv = {
375 .owner = THIS_MODULE,
376 .name = "gpio",
377 },
378 .probe = nmk_gpio_probe,
379 .remove = nmk_gpio_remove,
380 .suspend = NULL, /* to be done */
381 .resume = NULL,
382 .id_table = nmk_gpio_ids,
383};
384
385static int __init nmk_gpio_init(void)
386{
387 return amba_driver_register(&nmk_gpio_driver);
388}
389
390arch_initcall(nmk_gpio_init);
391
392MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
393MODULE_DESCRIPTION("Nomadik GPIO Driver");
394MODULE_LICENSE("GPL");
395
396
diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c
new file mode 100644
index 000000000000..abfe25a08d6b
--- /dev/null
+++ b/arch/arm/mach-nomadik/i2c-8815nhk.c
@@ -0,0 +1,65 @@
1#include <linux/module.h>
2#include <linux/init.h>
3#include <linux/i2c.h>
4#include <linux/i2c-algo-bit.h>
5#include <linux/i2c-gpio.h>
6#include <linux/gpio.h>
7#include <linux/platform_device.h>
8
9/*
10 * There are two busses in the 8815NHK.
11 * They could, in theory, be driven by the hardware component, but we
12 * use bit-bang through GPIO by now, to keep things simple
13 */
14
15static struct i2c_gpio_platform_data nhk8815_i2c_data0 = {
16 /* keep defaults for timeouts; pins are push-pull bidirectional */
17 .scl_pin = 62,
18 .sda_pin = 63,
19};
20
21static struct i2c_gpio_platform_data nhk8815_i2c_data1 = {
22 /* keep defaults for timeouts; pins are push-pull bidirectional */
23 .scl_pin = 53,
24 .sda_pin = 54,
25};
26
27/* first bus: GPIO XX and YY */
28static struct platform_device nhk8815_i2c_dev0 = {
29 .name = "i2c-gpio",
30 .id = 0,
31 .dev = {
32 .platform_data = &nhk8815_i2c_data0,
33 },
34};
35/* second bus: GPIO XX and YY */
36static struct platform_device nhk8815_i2c_dev1 = {
37 .name = "i2c-gpio",
38 .id = 1,
39 .dev = {
40 .platform_data = &nhk8815_i2c_data1,
41 },
42};
43
44static int __init nhk8815_i2c_init(void)
45{
46 nmk_gpio_set_mode(nhk8815_i2c_data0.scl_pin, NMK_GPIO_ALT_GPIO);
47 nmk_gpio_set_mode(nhk8815_i2c_data0.sda_pin, NMK_GPIO_ALT_GPIO);
48 platform_device_register(&nhk8815_i2c_dev0);
49
50 nmk_gpio_set_mode(nhk8815_i2c_data1.scl_pin, NMK_GPIO_ALT_GPIO);
51 nmk_gpio_set_mode(nhk8815_i2c_data1.sda_pin, NMK_GPIO_ALT_GPIO);
52 platform_device_register(&nhk8815_i2c_dev1);
53
54 return 0;
55}
56
57static void __exit nhk8815_i2c_exit(void)
58{
59 platform_device_unregister(&nhk8815_i2c_dev0);
60 platform_device_unregister(&nhk8815_i2c_dev1);
61 return;
62}
63
64module_init(nhk8815_i2c_init);
65module_exit(nhk8815_i2c_exit);
diff --git a/arch/arm/mach-nomadik/include/mach/clkdev.h b/arch/arm/mach-nomadik/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif
diff --git a/arch/arm/mach-nomadik/include/mach/debug-macro.S b/arch/arm/mach-nomadik/include/mach/debug-macro.S
new file mode 100644
index 000000000000..e876990e1569
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
1/*
2 * Debugging macro include header
3 *
4 * Copyright (C) 1994-1999 Russell King
5 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11*/
12
13 .macro addruart,rx
14 mrc p15, 0, \rx, c1, c0
15 tst \rx, #1 @ MMU enabled?
16 moveq \rx, #0x10000000 @ physical base address
17 movne \rx, #0xf0000000 @ virtual base
18 add \rx, \rx, #0x00100000
19 add \rx, \rx, #0x000fb000
20 .endm
21
22#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-nomadik/include/mach/entry-macro.S b/arch/arm/mach-nomadik/include/mach/entry-macro.S
new file mode 100644
index 000000000000..49f1aa3bb420
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/entry-macro.S
@@ -0,0 +1,43 @@
1/*
2 * Low-level IRQ helper macros for Nomadik platforms
3 *
4 * This file is licensed under the terms of the GNU General Public
5 * License version 2. This program is licensed "as is" without any
6 * warranty of any kind, whether express or implied.
7 */
8
9#include <mach/hardware.h>
10#include <mach/irqs.h>
11
12 .macro disable_fiq
13 .endm
14
15 .macro get_irqnr_preamble, base, tmp
16 ldr \base, =IO_ADDRESS(NOMADIK_IC_BASE)
17 .endm
18
19 .macro arch_ret_to_user, tmp1, tmp2
20 .endm
21
22 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
23
24 /* This stanza gets the irq mask from one of two status registers */
25 mov \irqnr, #0
26 ldr \irqstat, [\base, #VIC_REG_IRQSR0] @ get masked status
27 cmp \irqstat, #0
28 bne 1001f
29 add \irqnr, \irqnr, #32
30 ldr \irqstat, [\base, #VIC_REG_IRQSR1] @ get masked status
31
321001: tst \irqstat, #15
33 bne 1002f
34 add \irqnr, \irqnr, #4
35 movs \irqstat, \irqstat, lsr #4
36 bne 1001b
371002: tst \irqstat, #1
38 bne 1003f
39 add \irqnr, \irqnr, #1
40 movs \irqstat, \irqstat, lsr #1
41 bne 1002b
421003: /* EQ will be set if no irqs pending */
43 .endm
diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h
new file mode 100644
index 000000000000..61577c9f9a7d
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/gpio.h
@@ -0,0 +1,71 @@
1/*
2 * Structures and registers for GPIO access in the Nomadik SoC
3 *
4 * Copyright (C) 2008 STMicroelectronics
5 * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
6 * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __ASM_ARCH_GPIO_H
13#define __ASM_ARCH_GPIO_H
14
15#include <asm-generic/gpio.h>
16
17/*
18 * These currently cause a function call to happen, they may be optimized
19 * if needed by adding cpu-specific defines to identify blocks
20 * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
21 */
22#define gpio_get_value __gpio_get_value
23#define gpio_set_value __gpio_set_value
24#define gpio_cansleep __gpio_cansleep
25#define gpio_to_irq __gpio_to_irq
26
27/*
28 * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
29 * the "gpio" namespace for generic and cross-machine functions
30 */
31
32/* Register in the logic block */
33#define NMK_GPIO_DAT 0x00
34#define NMK_GPIO_DATS 0x04
35#define NMK_GPIO_DATC 0x08
36#define NMK_GPIO_PDIS 0x0c
37#define NMK_GPIO_DIR 0x10
38#define NMK_GPIO_DIRS 0x14
39#define NMK_GPIO_DIRC 0x18
40#define NMK_GPIO_SLPC 0x1c
41#define NMK_GPIO_AFSLA 0x20
42#define NMK_GPIO_AFSLB 0x24
43
44#define NMK_GPIO_RIMSC 0x40
45#define NMK_GPIO_FIMSC 0x44
46#define NMK_GPIO_IS 0x48
47#define NMK_GPIO_IC 0x4c
48#define NMK_GPIO_RWIMSC 0x50
49#define NMK_GPIO_FWIMSC 0x54
50#define NMK_GPIO_WKS 0x58
51
52/* Alternate functions: function C is set in hw by setting both A and B */
53#define NMK_GPIO_ALT_GPIO 0
54#define NMK_GPIO_ALT_A 1
55#define NMK_GPIO_ALT_B 2
56#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
57
58extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
59extern int nmk_gpio_get_mode(int gpio);
60
61/*
62 * Platform data to register a block: only the initial gpio/irq number.
63 */
64struct nmk_gpio_platform_data {
65 char *name;
66 int first_gpio;
67 int first_irq;
68 int parent_irq;
69};
70
71#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-nomadik/include/mach/hardware.h b/arch/arm/mach-nomadik/include/mach/hardware.h
new file mode 100644
index 000000000000..6316dba3bfc8
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/hardware.h
@@ -0,0 +1,90 @@
1/*
2 * This file contains the hardware definitions of the Nomadik.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * YOU should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef __ASM_ARCH_HARDWARE_H
19#define __ASM_ARCH_HARDWARE_H
20
21/* Nomadik registers live from 0x1000.0000 to 0x1023.0000 -- currently */
22#define NOMADIK_IO_VIRTUAL 0xF0000000 /* VA of IO */
23#define NOMADIK_IO_PHYSICAL 0x10000000 /* PA of IO */
24#define NOMADIK_IO_SIZE 0x00300000 /* 3MB for all regs */
25
26/* used in C code, so cast to proper type */
27#define io_p2v(x) ((void __iomem *)(x) \
28 - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
29#define io_v2p(x) ((unsigned long)(x) \
30 - NOMADIK_IO_VIRTUAL + NOMADIK_IO_PHYSICAL)
31
32/* used in asm code, so no casts */
33#define IO_ADDRESS(x) ((x) - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
34
35/*
36 * Base address defination for Nomadik Onchip Logic Block
37 */
38#define NOMADIK_FSMC_BASE 0x10100000 /* FSMC registers */
39#define NOMADIK_SDRAMC_BASE 0x10110000 /* SDRAM Controller */
40#define NOMADIK_CLCDC_BASE 0x10120000 /* CLCD Controller */
41#define NOMADIK_MDIF_BASE 0x10120000 /* MDIF */
42#define NOMADIK_DMA0_BASE 0x10130000 /* DMA0 Controller */
43#define NOMADIK_IC_BASE 0x10140000 /* Vectored Irq Controller */
44#define NOMADIK_DMA1_BASE 0x10150000 /* DMA1 Controller */
45#define NOMADIK_USB_BASE 0x10170000 /* USB-OTG conf reg base */
46#define NOMADIK_CRYP_BASE 0x10180000 /* Crypto processor */
47#define NOMADIK_SHA1_BASE 0x10190000 /* SHA-1 Processor */
48#define NOMADIK_XTI_BASE 0x101A0000 /* XTI */
49#define NOMADIK_RNG_BASE 0x101B0000 /* Random number generator */
50#define NOMADIK_SRC_BASE 0x101E0000 /* SRC base */
51#define NOMADIK_WDOG_BASE 0x101E1000 /* Watchdog */
52#define NOMADIK_MTU0_BASE 0x101E2000 /* Multiple Timer 0 */
53#define NOMADIK_MTU1_BASE 0x101E3000 /* Multiple Timer 1 */
54#define NOMADIK_GPIO0_BASE 0x101E4000 /* GPIO0 */
55#define NOMADIK_GPIO1_BASE 0x101E5000 /* GPIO1 */
56#define NOMADIK_GPIO2_BASE 0x101E6000 /* GPIO2 */
57#define NOMADIK_GPIO3_BASE 0x101E7000 /* GPIO3 */
58#define NOMADIK_RTC_BASE 0x101E8000 /* Real Time Clock base */
59#define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit */
60#define NOMADIK_OWM_BASE 0x101EA000 /* One wire master */
61#define NOMADIK_SCR_BASE 0x101EF000 /* Secure Control registers */
62#define NOMADIK_MSP2_BASE 0x101F0000 /* MSP 2 interface */
63#define NOMADIK_MSP1_BASE 0x101F1000 /* MSP 1 interface */
64#define NOMADIK_UART2_BASE 0x101F2000 /* UART 2 interface */
65#define NOMADIK_SSIRx_BASE 0x101F3000 /* SSI 8-ch rx interface */
66#define NOMADIK_SSITx_BASE 0x101F4000 /* SSI 8-ch tx interface */
67#define NOMADIK_MSHC_BASE 0x101F5000 /* Memory Stick(Pro) Host */
68#define NOMADIK_SDI_BASE 0x101F6000 /* SD-card/MM-Card */
69#define NOMADIK_I2C1_BASE 0x101F7000 /* I2C1 interface */
70#define NOMADIK_I2C0_BASE 0x101F8000 /* I2C0 interface */
71#define NOMADIK_MSP0_BASE 0x101F9000 /* MSP 0 interface */
72#define NOMADIK_FIRDA_BASE 0x101FA000 /* FIrDA interface */
73#define NOMADIK_UART1_BASE 0x101FB000 /* UART 1 interface */
74#define NOMADIK_SSP_BASE 0x101FC000 /* SSP interface */
75#define NOMADIK_UART0_BASE 0x101FD000 /* UART 0 interface */
76#define NOMADIK_SGA_BASE 0x101FE000 /* SGA interface */
77#define NOMADIK_L2CC_BASE 0x10210000 /* L2 Cache controller */
78
79/* Other ranges, not for p2v/v2p */
80#define NOMADIK_BACKUP_RAM 0x80010000
81#define NOMADIK_EBROM 0x80000000 /* Embedded boot ROM */
82#define NOMADIK_HAMACV_DMEM_BASE 0xA0100000 /* HAMACV Data Memory Start */
83#define NOMADIK_HAMACV_DMEM_END 0xA01FFFFF /* HAMACV Data Memory End */
84#define NOMADIK_HAMACA_DMEM 0xA0200000 /* HAMACA Data Memory Space */
85
86#define NOMADIK_FSMC_VA IO_ADDRESS(NOMADIK_FSMC_BASE)
87#define NOMADIK_MTU0_VA IO_ADDRESS(NOMADIK_MTU0_BASE)
88#define NOMADIK_MTU1_VA IO_ADDRESS(NOMADIK_MTU1_BASE)
89
90#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-nomadik/include/mach/io.h b/arch/arm/mach-nomadik/include/mach/io.h
new file mode 100644
index 000000000000..2e1eca1b8243
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/io.h
@@ -0,0 +1,22 @@
1/*
2 * arch/arm/mach-nomadik/include/mach/io.h (copied from mach-sa1100)
3 *
4 * Copyright (C) 1997-1999 Russell King
5 *
6 * Modifications:
7 * 06-12-1997 RMK Created.
8 * 07-04-1999 RMK Major cleanup
9 */
10#ifndef __ASM_ARM_ARCH_IO_H
11#define __ASM_ARM_ARCH_IO_H
12
13#define IO_SPACE_LIMIT 0xffffffff
14
15/*
16 * We don't actually have real ISA nor PCI buses, but there is so many
17 * drivers out there that might just work if we fake them...
18 */
19#define __io(a) __typesafe_io(a)
20#define __mem_pci(a) (a)
21
22#endif
diff --git a/arch/arm/mach-nomadik/include/mach/irqs.h b/arch/arm/mach-nomadik/include/mach/irqs.h
new file mode 100644
index 000000000000..8faabc560398
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/irqs.h
@@ -0,0 +1,82 @@
1/*
2 * mach-nomadik/include/mach/irqs.h
3 *
4 * Copyright (C) ST Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARCH_IRQS_H
21#define __ASM_ARCH_IRQS_H
22
23#include <mach/hardware.h>
24
25#define IRQ_VIC_START 0 /* first VIC interrupt is 0 */
26
27/*
28 * Interrupt numbers generic for all Nomadik Chip cuts
29 */
30#define IRQ_WATCHDOG 0
31#define IRQ_SOFTINT 1
32#define IRQ_CRYPTO 2
33#define IRQ_OWM 3
34#define IRQ_MTU0 4
35#define IRQ_MTU1 5
36#define IRQ_GPIO0 6
37#define IRQ_GPIO1 7
38#define IRQ_GPIO2 8
39#define IRQ_GPIO3 9
40#define IRQ_RTC_RTT 10
41#define IRQ_SSP 11
42#define IRQ_UART0 12
43#define IRQ_DMA1 13
44#define IRQ_CLCD_MDIF 14
45#define IRQ_DMA0 15
46#define IRQ_PWRFAIL 16
47#define IRQ_UART1 17
48#define IRQ_FIRDA 18
49#define IRQ_MSP0 19
50#define IRQ_I2C0 20
51#define IRQ_I2C1 21
52#define IRQ_SDMMC 22
53#define IRQ_USBOTG 23
54#define IRQ_SVA_IT0 24
55#define IRQ_SVA_IT1 25
56#define IRQ_SAA_IT0 26
57#define IRQ_SAA_IT1 27
58#define IRQ_UART2 28
59#define IRQ_MSP2 31
60#define IRQ_L2CC 48
61#define IRQ_HPI 49
62#define IRQ_SKE 50
63#define IRQ_KP 51
64#define IRQ_MEMST 54
65#define IRQ_SGA_IT 58
66#define IRQ_USBM 60
67#define IRQ_MSP1 62
68
69#define NOMADIK_SOC_NR_IRQS 64
70
71/* After chip-specific IRQ numbers we have the GPIO ones */
72#define NOMADIK_NR_GPIO 128 /* last 4 not wired to pins */
73#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + NOMADIK_SOC_NR_IRQS)
74#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - NOMADIK_SOC_NR_IRQS)
75#define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
76
77/* Following two are used by entry_macro.S, to access our dual-vic */
78#define VIC_REG_IRQSR0 0
79#define VIC_REG_IRQSR1 0x20
80
81#endif /* __ASM_ARCH_IRQS_H */
82
diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h
new file mode 100644
index 000000000000..1e5689d98ecd
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/memory.h
@@ -0,0 +1,28 @@
1/*
2 * mach-nomadik/include/mach/memory.h
3 *
4 * Copyright (C) 1999 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARCH_MEMORY_H
21#define __ASM_ARCH_MEMORY_H
22
23/*
24 * Physical DRAM offset.
25 */
26#define PHYS_OFFSET UL(0x00000000)
27
28#endif
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h
new file mode 100644
index 000000000000..76da7f085330
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/mtu.h
@@ -0,0 +1,45 @@
1#ifndef __ASM_ARCH_MTU_H
2#define __ASM_ARCH_MTU_H
3
4/*
5 * The MTU device hosts four different counters, with 4 set of
6 * registers. These are register names.
7 */
8
9#define MTU_IMSC 0x00 /* Interrupt mask set/clear */
10#define MTU_RIS 0x04 /* Raw interrupt status */
11#define MTU_MIS 0x08 /* Masked interrupt status */
12#define MTU_ICR 0x0C /* Interrupt clear register */
13
14/* per-timer registers take 0..3 as argument */
15#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */
16#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */
17#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */
18#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */
19
20/* bits for the control register */
21#define MTU_CRn_ENA 0x80
22#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */
23#define MTU_CRn_PRESCALE_MASK 0x0c
24#define MTU_CRn_PRESCALE_1 0x00
25#define MTU_CRn_PRESCALE_16 0x04
26#define MTU_CRn_PRESCALE_256 0x08
27#define MTU_CRn_32BITS 0x02
28#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/
29
30/* Other registers are usual amba/primecell registers, currently not used */
31#define MTU_ITCR 0xff0
32#define MTU_ITOP 0xff4
33
34#define MTU_PERIPH_ID0 0xfe0
35#define MTU_PERIPH_ID1 0xfe4
36#define MTU_PERIPH_ID2 0xfe8
37#define MTU_PERIPH_ID3 0xfeC
38
39#define MTU_PCELL0 0xff0
40#define MTU_PCELL1 0xff4
41#define MTU_PCELL2 0xff8
42#define MTU_PCELL3 0xffC
43
44#endif /* __ASM_ARCH_MTU_H */
45
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h
new file mode 100644
index 000000000000..a4e468cf63da
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/setup.h
@@ -0,0 +1,22 @@
1
2/*
3 * These symbols are needed for board-specific files to call their
4 * own cpu-specific files
5 */
6
7#ifndef __ASM_ARCH_SETUP_H
8#define __ASM_ARCH_SETUP_H
9
10#include <asm/mach/time.h>
11#include <linux/init.h>
12
13#ifdef CONFIG_NOMADIK_8815
14
15extern void cpu8815_map_io(void);
16extern void cpu8815_platform_init(void);
17extern void cpu8815_init_irq(void);
18extern struct sys_timer nomadik_timer;
19
20#endif /* NOMADIK_8815 */
21
22#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h
new file mode 100644
index 000000000000..7119f688116e
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/system.h
@@ -0,0 +1,45 @@
1/*
2 * mach-nomadik/include/mach/system.h
3 *
4 * Copyright (C) 2008 STMicroelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARCH_SYSTEM_H
21#define __ASM_ARCH_SYSTEM_H
22
23#include <linux/io.h>
24#include <mach/hardware.h>
25
26static inline void arch_idle(void)
27{
28 /*
29 * This should do all the clock switching
30 * and wait for interrupt tricks
31 */
32 cpu_do_idle();
33}
34
35static inline void arch_reset(char mode, const char *cmd)
36{
37 void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18);
38
39 /* FIXME: use egpio when implemented */
40
41 /* Write anything to Reset status register */
42 writel(1, src_rstsr);
43}
44
45#endif
diff --git a/arch/arm/mach-nomadik/include/mach/timex.h b/arch/arm/mach-nomadik/include/mach/timex.h
new file mode 100644
index 000000000000..318b8896ce96
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/timex.h
@@ -0,0 +1,6 @@
1#ifndef __ASM_ARCH_TIMEX_H
2#define __ASM_ARCH_TIMEX_H
3
4#define CLOCK_TICK_RATE 2400000
5
6#endif
diff --git a/arch/arm/mach-nomadik/include/mach/uncompress.h b/arch/arm/mach-nomadik/include/mach/uncompress.h
new file mode 100644
index 000000000000..071003bc8456
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/uncompress.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2008 STMicroelectronics
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef __ASM_ARCH_UNCOMPRESS_H
20#define __ASM_ARCH_UNCOMPRESS_H
21
22#include <asm/setup.h>
23#include <asm/io.h>
24#include <mach/hardware.h>
25
26/* we need the constants in amba/serial.h, but it refers to amba_device */
27struct amba_device;
28#include <linux/amba/serial.h>
29
30#define NOMADIK_UART_DR 0x101FB000
31#define NOMADIK_UART_LCRH 0x101FB02c
32#define NOMADIK_UART_CR 0x101FB030
33#define NOMADIK_UART_FR 0x101FB018
34
35static void putc(const char c)
36{
37 /* Do nothing if the UART is not enabled. */
38 if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
39 return;
40
41 if (c == '\n')
42 putc('\r');
43
44 while (readb(NOMADIK_UART_FR) & UART01x_FR_TXFF)
45 barrier();
46 writeb(c, NOMADIK_UART_DR);
47}
48
49static void flush(void)
50{
51 if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
52 return;
53 while (readb(NOMADIK_UART_FR) & UART01x_FR_BUSY)
54 barrier();
55}
56
57static inline void arch_decomp_setup(void)
58{
59}
60
61#define arch_decomp_wdog() /* nothing to do here */
62
63#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-nomadik/include/mach/vmalloc.h b/arch/arm/mach-nomadik/include/mach/vmalloc.h
new file mode 100644
index 000000000000..be12e31ea528
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/vmalloc.h
@@ -0,0 +1,2 @@
1
2#define VMALLOC_END 0xe8000000
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c
new file mode 100644
index 000000000000..d1738e7061d4
--- /dev/null
+++ b/arch/arm/mach-nomadik/timer.c
@@ -0,0 +1,164 @@
1/*
2 * linux/arch/arm/mach-nomadik/timer.c
3 *
4 * Copyright (C) 2008 STMicroelectronics
5 * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14#include <linux/io.h>
15#include <linux/clockchips.h>
16#include <linux/jiffies.h>
17#include <asm/mach/time.h>
18#include <mach/mtu.h>
19
20#define TIMER_CTRL 0x80 /* No divisor */
21#define TIMER_PERIODIC 0x40
22#define TIMER_SZ32BIT 0x02
23
24/* Initial value for SRC control register: all timers use MXTAL/8 source */
25#define SRC_CR_INIT_MASK 0x00007fff
26#define SRC_CR_INIT_VAL 0x2aaa8000
27
28static u32 nmdk_count; /* accumulated count */
29static u32 nmdk_cycle; /* write-once */
30static __iomem void *mtu_base;
31
32/*
33 * clocksource: the MTU device is a decrementing counters, so we negate
34 * the value being read.
35 */
36static cycle_t nmdk_read_timer(struct clocksource *cs)
37{
38 u32 count = readl(mtu_base + MTU_VAL(0));
39 return nmdk_count + nmdk_cycle - count;
40
41}
42
43static struct clocksource nmdk_clksrc = {
44 .name = "mtu_0",
45 .rating = 120,
46 .read = nmdk_read_timer,
47 .shift = 20,
48 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
49};
50
51/*
52 * Clockevent device: currently only periodic mode is supported
53 */
54static void nmdk_clkevt_mode(enum clock_event_mode mode,
55 struct clock_event_device *dev)
56{
57 unsigned long flags;
58
59 switch (mode) {
60 case CLOCK_EVT_MODE_PERIODIC:
61 /* enable interrupts -- and count current value? */
62 raw_local_irq_save(flags);
63 writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
64 raw_local_irq_restore(flags);
65 break;
66 case CLOCK_EVT_MODE_ONESHOT:
67 BUG(); /* Not supported, yet */
68 /* FALLTHROUGH */
69 case CLOCK_EVT_MODE_SHUTDOWN:
70 case CLOCK_EVT_MODE_UNUSED:
71 /* disable irq */
72 raw_local_irq_save(flags);
73 writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
74 raw_local_irq_restore(flags);
75 break;
76 case CLOCK_EVT_MODE_RESUME:
77 break;
78 }
79}
80
81static struct clock_event_device nmdk_clkevt = {
82 .name = "mtu_0",
83 .features = CLOCK_EVT_FEAT_PERIODIC,
84 .shift = 32,
85 .rating = 100,
86 .set_mode = nmdk_clkevt_mode,
87};
88
89/*
90 * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
91 * as we are the only users of mtu0 by now.
92 */
93static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
94{
95 /* ack: "interrupt clear register" */
96 writel( 1 << 0, mtu_base + MTU_ICR);
97
98 /* we can't count lost ticks, unfortunately */
99 nmdk_count += nmdk_cycle;
100 nmdk_clkevt.event_handler(&nmdk_clkevt);
101
102 return IRQ_HANDLED;
103}
104
105/*
106 * Set up timer interrupt, and return the current time in seconds.
107 */
108static struct irqaction nmdk_timer_irq = {
109 .name = "Nomadik Timer Tick",
110 .flags = IRQF_DISABLED | IRQF_TIMER,
111 .handler = nmdk_timer_interrupt,
112};
113
114static void nmdk_timer_reset(void)
115{
116 u32 cr;
117
118 writel(0, mtu_base + MTU_CR(0)); /* off */
119
120 /* configure load and background-load, and fire it up */
121 writel(nmdk_cycle, mtu_base + MTU_LR(0));
122 writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
123 cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
124 writel(cr, mtu_base + MTU_CR(0));
125 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
126}
127
128static void __init nmdk_timer_init(void)
129{
130 u32 src_cr;
131 unsigned long rate;
132 int bits;
133
134 rate = CLOCK_TICK_RATE; /* 2.4MHz */
135 nmdk_cycle = (rate + HZ/2) / HZ;
136
137 /* Configure timer sources in "system reset controller" ctrl reg */
138 src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
139 src_cr &= SRC_CR_INIT_MASK;
140 src_cr |= SRC_CR_INIT_VAL;
141 writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
142
143 /* Save global pointer to mtu, used by functions above */
144 mtu_base = io_p2v(NOMADIK_MTU0_BASE);
145
146 /* Init the timer and register clocksource */
147 nmdk_timer_reset();
148
149 nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
150 bits = 8*sizeof(nmdk_count);
151 nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
152
153 clocksource_register(&nmdk_clksrc);
154
155 /* Register irq and clockevents */
156 setup_irq(IRQ_MTU0, &nmdk_timer_irq);
157 nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
158 nmdk_clkevt.cpumask = cpumask_of(0);
159 clockevents_register_device(&nmdk_clkevt);
160}
161
162struct sys_timer nomadik_timer = {
163 .init = nmdk_timer_init,
164};
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index b0c7402248f7..1b223076ceb7 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -39,7 +39,7 @@ static struct platform_device *sdp4430_devices[] __initdata = {
39}; 39};
40 40
41static struct omap_uart_config sdp4430_uart_config __initdata = { 41static struct omap_uart_config sdp4430_uart_config __initdata = {
42 .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2), 42 .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
43}; 43};
44 44
45static struct omap_lcd_config sdp4430_lcd_config __initdata = { 45static struct omap_lcd_config sdp4430_lcd_config __initdata = {
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 99b6e1546311..a846aa1ebb4d 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -128,6 +128,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
128 .rx_irq = INT_24XX_MCBSP1_IRQ_RX, 128 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
129 .tx_irq = INT_24XX_MCBSP1_IRQ_TX, 129 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
130 .ops = &omap2_mcbsp_ops, 130 .ops = &omap2_mcbsp_ops,
131 .buffer_size = 0x6F,
131 }, 132 },
132 { 133 {
133 .phys_base = OMAP34XX_MCBSP2_BASE, 134 .phys_base = OMAP34XX_MCBSP2_BASE,
@@ -136,6 +137,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
136 .rx_irq = INT_24XX_MCBSP2_IRQ_RX, 137 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
137 .tx_irq = INT_24XX_MCBSP2_IRQ_TX, 138 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
138 .ops = &omap2_mcbsp_ops, 139 .ops = &omap2_mcbsp_ops,
140 .buffer_size = 0x3FF,
139 }, 141 },
140 { 142 {
141 .phys_base = OMAP34XX_MCBSP3_BASE, 143 .phys_base = OMAP34XX_MCBSP3_BASE,
@@ -144,6 +146,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
144 .rx_irq = INT_24XX_MCBSP3_IRQ_RX, 146 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
145 .tx_irq = INT_24XX_MCBSP3_IRQ_TX, 147 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
146 .ops = &omap2_mcbsp_ops, 148 .ops = &omap2_mcbsp_ops,
149 .buffer_size = 0x6F,
147 }, 150 },
148 { 151 {
149 .phys_base = OMAP34XX_MCBSP4_BASE, 152 .phys_base = OMAP34XX_MCBSP4_BASE,
@@ -152,6 +155,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
152 .rx_irq = INT_24XX_MCBSP4_IRQ_RX, 155 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
153 .tx_irq = INT_24XX_MCBSP4_IRQ_TX, 156 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
154 .ops = &omap2_mcbsp_ops, 157 .ops = &omap2_mcbsp_ops,
158 .buffer_size = 0x6F,
155 }, 159 },
156 { 160 {
157 .phys_base = OMAP34XX_MCBSP5_BASE, 161 .phys_base = OMAP34XX_MCBSP5_BASE,
@@ -160,6 +164,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
160 .rx_irq = INT_24XX_MCBSP5_IRQ_RX, 164 .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
161 .tx_irq = INT_24XX_MCBSP5_IRQ_TX, 165 .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
162 .ops = &omap2_mcbsp_ops, 166 .ops = &omap2_mcbsp_ops,
167 .buffer_size = 0x6F,
163 }, 168 },
164}; 169};
165#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) 170#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
@@ -168,6 +173,42 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
168#define OMAP34XX_MCBSP_PDATA_SZ 0 173#define OMAP34XX_MCBSP_PDATA_SZ 0
169#endif 174#endif
170 175
176static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
177 {
178 .phys_base = OMAP44XX_MCBSP1_BASE,
179 .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX,
180 .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX,
181 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
182 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
183 .ops = &omap2_mcbsp_ops,
184 },
185 {
186 .phys_base = OMAP44XX_MCBSP2_BASE,
187 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
188 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
189 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
190 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
191 .ops = &omap2_mcbsp_ops,
192 },
193 {
194 .phys_base = OMAP44XX_MCBSP3_BASE,
195 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
196 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
197 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
198 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
199 .ops = &omap2_mcbsp_ops,
200 },
201 {
202 .phys_base = OMAP44XX_MCBSP4_BASE,
203 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
204 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
205 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
206 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
207 .ops = &omap2_mcbsp_ops,
208 },
209};
210#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata)
211
171static int __init omap2_mcbsp_init(void) 212static int __init omap2_mcbsp_init(void)
172{ 213{
173 if (cpu_is_omap2420()) 214 if (cpu_is_omap2420())
@@ -176,6 +217,8 @@ static int __init omap2_mcbsp_init(void)
176 omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; 217 omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
177 if (cpu_is_omap34xx()) 218 if (cpu_is_omap34xx())
178 omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; 219 omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
220 if (cpu_is_omap44xx())
221 omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
179 222
180 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), 223 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
181 GFP_KERNEL); 224 GFP_KERNEL);
@@ -191,6 +234,9 @@ static int __init omap2_mcbsp_init(void)
191 if (cpu_is_omap34xx()) 234 if (cpu_is_omap34xx())
192 omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, 235 omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
193 OMAP34XX_MCBSP_PDATA_SZ); 236 OMAP34XX_MCBSP_PDATA_SZ);
237 if (cpu_is_omap44xx())
238 omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
239 OMAP44XX_MCBSP_PDATA_SZ);
194 240
195 return omap_mcbsp_init(); 241 return omap_mcbsp_init();
196} 242}
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index a7421a50410b..ce22344b94e7 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -109,6 +109,16 @@ static struct plat_serial8250_port serial_platform_data2[] = {
109 .regshift = 2, 109 .regshift = 2,
110 .uartclk = OMAP24XX_BASE_BAUD * 16, 110 .uartclk = OMAP24XX_BASE_BAUD * 16,
111 }, { 111 }, {
112#ifdef CONFIG_ARCH_OMAP4
113 .membase = IO_ADDRESS(OMAP_UART4_BASE),
114 .mapbase = OMAP_UART4_BASE,
115 .irq = 70,
116 .flags = UPF_BOOT_AUTOCONF,
117 .iotype = UPIO_MEM,
118 .regshift = 2,
119 .uartclk = OMAP24XX_BASE_BAUD * 16,
120 }, {
121#endif
112 .flags = 0 122 .flags = 0
113 } 123 }
114}; 124};
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 2c7035d8dcbf..c3d513cad5ac 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -89,6 +89,27 @@ config MACH_EDMINI_V2
89 Say 'Y' here if you want your kernel to support the 89 Say 'Y' here if you want your kernel to support the
90 LaCie Ethernet Disk mini V2. 90 LaCie Ethernet Disk mini V2.
91 91
92config MACH_D2NET
93 bool "LaCie d2 Network"
94 select I2C_BOARDINFO
95 help
96 Say 'Y' here if you want your kernel to support the
97 LaCie d2 Network NAS.
98
99config MACH_BIGDISK
100 bool "LaCie Big Disk Network"
101 select I2C_BOARDINFO
102 help
103 Say 'Y' here if you want your kernel to support the
104 LaCie Big Disk Network NAS.
105
106config MACH_NET2BIG
107 bool "LaCie 2Big Network"
108 select I2C_BOARDINFO
109 help
110 Say 'Y' here if you want your kernel to support the
111 LaCie 2Big Network NAS.
112
92config MACH_MSS2 113config MACH_MSS2
93 bool "Maxtor Shared Storage II" 114 bool "Maxtor Shared Storage II"
94 help 115 help
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index edc38e2c856f..89772fcd65c7 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -12,6 +12,9 @@ obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o
12obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o 12obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o
13obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o 13obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o
14obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o 14obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o
15obj-$(CONFIG_MACH_D2NET) += d2net-setup.o
16obj-$(CONFIG_MACH_BIGDISK) += d2net-setup.o
17obj-$(CONFIG_MACH_NET2BIG) += net2big-setup.o
15obj-$(CONFIG_MACH_MSS2) += mss2-setup.o 18obj-$(CONFIG_MACH_MSS2) += mss2-setup.o
16obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o 19obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
17obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o 20obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index d78731edebb6..1a5d6a0e2602 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -84,7 +84,8 @@ static int __init orion5x_cpu_win_can_remap(int win)
84 orion5x_pcie_id(&dev, &rev); 84 orion5x_pcie_id(&dev, &rev);
85 if ((dev == MV88F5281_DEV_ID && win < 4) 85 if ((dev == MV88F5281_DEV_ID && win < 4)
86 || (dev == MV88F5182_DEV_ID && win < 2) 86 || (dev == MV88F5182_DEV_ID && win < 2)
87 || (dev == MV88F5181_DEV_ID && win < 2)) 87 || (dev == MV88F5181_DEV_ID && win < 2)
88 || (dev == MV88F6183_DEV_ID && win < 4))
88 return 1; 89 return 1;
89 90
90 return 0; 91 return 0;
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c
new file mode 100644
index 000000000000..9d4bf763f25b
--- /dev/null
+++ b/arch/arm/mach-orion5x/d2net-setup.c
@@ -0,0 +1,365 @@
1/*
2 * arch/arm/mach-orion5x/d2net-setup.c
3 *
4 * LaCie d2Network and Big Disk Network NAS setup
5 *
6 * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/pci.h>
17#include <linux/irq.h>
18#include <linux/mtd/physmap.h>
19#include <linux/mv643xx_eth.h>
20#include <linux/leds.h>
21#include <linux/gpio_keys.h>
22#include <linux/input.h>
23#include <linux/i2c.h>
24#include <linux/ata_platform.h>
25#include <linux/gpio.h>
26#include <asm/mach-types.h>
27#include <asm/mach/arch.h>
28#include <asm/mach/pci.h>
29#include <mach/orion5x.h>
30#include "common.h"
31#include "mpp.h"
32
33/*****************************************************************************
34 * LaCie d2 Network Info
35 ****************************************************************************/
36
37/*
38 * 512KB NOR flash Device bus boot chip select
39 */
40
41#define D2NET_NOR_BOOT_BASE 0xfff80000
42#define D2NET_NOR_BOOT_SIZE SZ_512K
43
44/*****************************************************************************
45 * 512KB NOR Flash on Boot Device
46 ****************************************************************************/
47
48/*
49 * TODO: Check write support on flash MX29LV400CBTC-70G
50 */
51
52static struct mtd_partition d2net_partitions[] = {
53 {
54 .name = "Full512kb",
55 .size = MTDPART_SIZ_FULL,
56 .offset = 0,
57 .mask_flags = MTD_WRITEABLE,
58 },
59};
60
61static struct physmap_flash_data d2net_nor_flash_data = {
62 .width = 1,
63 .parts = d2net_partitions,
64 .nr_parts = ARRAY_SIZE(d2net_partitions),
65};
66
67static struct resource d2net_nor_flash_resource = {
68 .flags = IORESOURCE_MEM,
69 .start = D2NET_NOR_BOOT_BASE,
70 .end = D2NET_NOR_BOOT_BASE
71 + D2NET_NOR_BOOT_SIZE - 1,
72};
73
74static struct platform_device d2net_nor_flash = {
75 .name = "physmap-flash",
76 .id = 0,
77 .dev = {
78 .platform_data = &d2net_nor_flash_data,
79 },
80 .num_resources = 1,
81 .resource = &d2net_nor_flash_resource,
82};
83
84/*****************************************************************************
85 * Ethernet
86 ****************************************************************************/
87
88static struct mv643xx_eth_platform_data d2net_eth_data = {
89 .phy_addr = MV643XX_ETH_PHY_ADDR(8),
90};
91
92/*****************************************************************************
93 * I2C devices
94 ****************************************************************************/
95
96/*
97 * i2c addr | chip | description
98 * 0x32 | Ricoh 5C372b | RTC
99 * 0x3e | GMT G762 | PWM fan controller
100 * 0x50 | HT24LC08 | eeprom (1kB)
101 *
102 * TODO: Add G762 support to the g760a driver.
103 */
104static struct i2c_board_info __initdata d2net_i2c_devices[] = {
105 {
106 I2C_BOARD_INFO("rs5c372b", 0x32),
107 }, {
108 I2C_BOARD_INFO("24c08", 0x50),
109 },
110};
111
112/*****************************************************************************
113 * SATA
114 ****************************************************************************/
115
116static struct mv_sata_platform_data d2net_sata_data = {
117 .n_ports = 2,
118};
119
120#define D2NET_GPIO_SATA0_POWER 3
121#define D2NET_GPIO_SATA1_POWER 12
122
123static void __init d2net_sata_power_init(void)
124{
125 int err;
126
127 err = gpio_request(D2NET_GPIO_SATA0_POWER, "SATA0 power");
128 if (err == 0) {
129 err = gpio_direction_output(D2NET_GPIO_SATA0_POWER, 1);
130 if (err)
131 gpio_free(D2NET_GPIO_SATA0_POWER);
132 }
133 if (err)
134 pr_err("d2net: failed to configure SATA0 power GPIO\n");
135
136 err = gpio_request(D2NET_GPIO_SATA1_POWER, "SATA1 power");
137 if (err == 0) {
138 err = gpio_direction_output(D2NET_GPIO_SATA1_POWER, 1);
139 if (err)
140 gpio_free(D2NET_GPIO_SATA1_POWER);
141 }
142 if (err)
143 pr_err("d2net: failed to configure SATA1 power GPIO\n");
144}
145
146/*****************************************************************************
147 * GPIO LED's
148 ****************************************************************************/
149
150/*
151 * The blue front LED is wired to the CPLD and can blink in relation with the
152 * SATA activity. This feature is disabled to make this LED compatible with
153 * the leds-gpio driver: MPP14 and MPP15 are configured to act like output
154 * GPIO's and have to stay in an active state. This is needed to set the blue
155 * LED in a "fix on" state regardless of the SATA activity.
156 *
157 * The following array detail the different LED registers and the combination
158 * of their possible values:
159 *
160 * led_off | blink_ctrl | SATA active | LED state
161 * | | |
162 * 1 | x | x | off
163 * 0 | 0 | 0 | off
164 * 0 | 1 | 0 | blink (rate 300ms)
165 * 0 | x | 1 | on
166 *
167 * Notes: The blue and the red front LED's can't be on at the same time.
168 * Red LED have priority.
169 */
170
171#define D2NET_GPIO_RED_LED 6
172#define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16
173#define D2NET_GPIO_BLUE_LED_OFF 23
174#define D2NET_GPIO_SATA0_ACT 14
175#define D2NET_GPIO_SATA1_ACT 15
176
177static struct gpio_led d2net_leds[] = {
178 {
179 .name = "d2net:blue:power",
180 .gpio = D2NET_GPIO_BLUE_LED_OFF,
181 .active_low = 1,
182 },
183 {
184 .name = "d2net:red:fail",
185 .gpio = D2NET_GPIO_RED_LED,
186 },
187};
188
189static struct gpio_led_platform_data d2net_led_data = {
190 .num_leds = ARRAY_SIZE(d2net_leds),
191 .leds = d2net_leds,
192};
193
194static struct platform_device d2net_gpio_leds = {
195 .name = "leds-gpio",
196 .id = -1,
197 .dev = {
198 .platform_data = &d2net_led_data,
199 },
200};
201
202static void __init d2net_gpio_leds_init(void)
203{
204 /* Configure GPIO over MPP max number. */
205 orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1);
206
207 if (gpio_request(D2NET_GPIO_SATA0_ACT, "LED SATA0 activity") != 0)
208 return;
209 if (gpio_direction_output(D2NET_GPIO_SATA0_ACT, 1) != 0)
210 goto err_free_1;
211 if (gpio_request(D2NET_GPIO_SATA1_ACT, "LED SATA1 activity") != 0)
212 goto err_free_1;
213 if (gpio_direction_output(D2NET_GPIO_SATA1_ACT, 1) != 0)
214 goto err_free_2;
215 platform_device_register(&d2net_gpio_leds);
216 return;
217
218err_free_2:
219 gpio_free(D2NET_GPIO_SATA1_ACT);
220err_free_1:
221 gpio_free(D2NET_GPIO_SATA0_ACT);
222 return;
223}
224
225/****************************************************************************
226 * GPIO keys
227 ****************************************************************************/
228
229#define D2NET_GPIO_PUSH_BUTTON 18
230#define D2NET_GPIO_POWER_SWITCH_ON 8
231#define D2NET_GPIO_POWER_SWITCH_OFF 9
232
233#define D2NET_SWITCH_POWER_ON 0x1
234#define D2NET_SWITCH_POWER_OFF 0x2
235
236static struct gpio_keys_button d2net_buttons[] = {
237 {
238 .type = EV_SW,
239 .code = D2NET_SWITCH_POWER_OFF,
240 .gpio = D2NET_GPIO_POWER_SWITCH_OFF,
241 .desc = "Power rocker switch (auto|off)",
242 .active_low = 0,
243 },
244 {
245 .type = EV_SW,
246 .code = D2NET_SWITCH_POWER_ON,
247 .gpio = D2NET_GPIO_POWER_SWITCH_ON,
248 .desc = "Power rocker switch (on|auto)",
249 .active_low = 0,
250 },
251 {
252 .type = EV_KEY,
253 .code = KEY_POWER,
254 .gpio = D2NET_GPIO_PUSH_BUTTON,
255 .desc = "Front Push Button",
256 .active_low = 0,
257 },
258};
259
260static struct gpio_keys_platform_data d2net_button_data = {
261 .buttons = d2net_buttons,
262 .nbuttons = ARRAY_SIZE(d2net_buttons),
263};
264
265static struct platform_device d2net_gpio_buttons = {
266 .name = "gpio-keys",
267 .id = -1,
268 .dev = {
269 .platform_data = &d2net_button_data,
270 },
271};
272
273/*****************************************************************************
274 * General Setup
275 ****************************************************************************/
276
277static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = {
278 { 0, MPP_GPIO }, /* Board ID (bit 0) */
279 { 1, MPP_GPIO }, /* Board ID (bit 1) */
280 { 2, MPP_GPIO }, /* Board ID (bit 2) */
281 { 3, MPP_GPIO }, /* SATA 0 power */
282 { 4, MPP_UNUSED },
283 { 5, MPP_GPIO }, /* Fan fail detection */
284 { 6, MPP_GPIO }, /* Red front LED */
285 { 7, MPP_UNUSED },
286 { 8, MPP_GPIO }, /* Rear power switch (on|auto) */
287 { 9, MPP_GPIO }, /* Rear power switch (auto|off) */
288 { 10, MPP_UNUSED },
289 { 11, MPP_UNUSED },
290 { 12, MPP_GPIO }, /* SATA 1 power */
291 { 13, MPP_UNUSED },
292 { 14, MPP_GPIO }, /* SATA 0 active */
293 { 15, MPP_GPIO }, /* SATA 1 active */
294 { 16, MPP_GPIO }, /* Blue front LED blink control */
295 { 17, MPP_UNUSED },
296 { 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */
297 { 19, MPP_UNUSED },
298 { -1 }
299 /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
300 /* 23: Blue front LED off */
301 /* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
302};
303
304static void __init d2net_init(void)
305{
306 /*
307 * Setup basic Orion functions. Need to be called early.
308 */
309 orion5x_init();
310
311 orion5x_mpp_conf(d2net_mpp_modes);
312
313 /*
314 * Configure peripherals.
315 */
316 orion5x_ehci0_init();
317 orion5x_eth_init(&d2net_eth_data);
318 orion5x_i2c_init();
319 orion5x_uart0_init();
320
321 d2net_sata_power_init();
322 orion5x_sata_init(&d2net_sata_data);
323
324 orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE,
325 D2NET_NOR_BOOT_SIZE);
326 platform_device_register(&d2net_nor_flash);
327
328 platform_device_register(&d2net_gpio_buttons);
329
330 d2net_gpio_leds_init();
331
332 pr_notice("d2net: Flash write are not yet supported.\n");
333
334 i2c_register_board_info(0, d2net_i2c_devices,
335 ARRAY_SIZE(d2net_i2c_devices));
336}
337
338/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
339
340#ifdef CONFIG_MACH_D2NET
341MACHINE_START(D2NET, "LaCie d2 Network")
342 .phys_io = ORION5X_REGS_PHYS_BASE,
343 .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
344 .boot_params = 0x00000100,
345 .init_machine = d2net_init,
346 .map_io = orion5x_map_io,
347 .init_irq = orion5x_init_irq,
348 .timer = &orion5x_timer,
349 .fixup = tag_fixup_mem32,
350MACHINE_END
351#endif
352
353#ifdef CONFIG_MACH_BIGDISK
354MACHINE_START(BIGDISK, "LaCie Big Disk Network")
355 .phys_io = ORION5X_REGS_PHYS_BASE,
356 .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
357 .boot_params = 0x00000100,
358 .init_machine = d2net_init,
359 .map_io = orion5x_map_io,
360 .init_irq = orion5x_init_irq,
361 .timer = &orion5x_timer,
362 .fixup = tag_fixup_mem32,
363MACHINE_END
364#endif
365
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
new file mode 100644
index 000000000000..7bd6283476f9
--- /dev/null
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -0,0 +1,431 @@
1/*
2 * arch/arm/mach-orion5x/net2big-setup.c
3 *
4 * LaCie 2Big Network NAS setup
5 *
6 * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/mtd/physmap.h>
17#include <linux/mv643xx_eth.h>
18#include <linux/leds.h>
19#include <linux/gpio_keys.h>
20#include <linux/input.h>
21#include <linux/i2c.h>
22#include <linux/ata_platform.h>
23#include <linux/gpio.h>
24#include <linux/delay.h>
25#include <asm/mach-types.h>
26#include <asm/mach/arch.h>
27#include <mach/orion5x.h>
28#include "common.h"
29#include "mpp.h"
30
31/*****************************************************************************
32 * LaCie 2Big Network Info
33 ****************************************************************************/
34
35/*
36 * 512KB NOR flash Device bus boot chip select
37 */
38
39#define NET2BIG_NOR_BOOT_BASE 0xfff80000
40#define NET2BIG_NOR_BOOT_SIZE SZ_512K
41
42/*****************************************************************************
43 * 512KB NOR Flash on Boot Device
44 ****************************************************************************/
45
46/*
47 * TODO: Check write support on flash MX29LV400CBTC-70G
48 */
49
50static struct mtd_partition net2big_partitions[] = {
51 {
52 .name = "Full512kb",
53 .size = MTDPART_SIZ_FULL,
54 .offset = 0x00000000,
55 .mask_flags = MTD_WRITEABLE,
56 },
57};
58
59static struct physmap_flash_data net2big_nor_flash_data = {
60 .width = 1,
61 .parts = net2big_partitions,
62 .nr_parts = ARRAY_SIZE(net2big_partitions),
63};
64
65static struct resource net2big_nor_flash_resource = {
66 .flags = IORESOURCE_MEM,
67 .start = NET2BIG_NOR_BOOT_BASE,
68 .end = NET2BIG_NOR_BOOT_BASE
69 + NET2BIG_NOR_BOOT_SIZE - 1,
70};
71
72static struct platform_device net2big_nor_flash = {
73 .name = "physmap-flash",
74 .id = 0,
75 .dev = {
76 .platform_data = &net2big_nor_flash_data,
77 },
78 .num_resources = 1,
79 .resource = &net2big_nor_flash_resource,
80};
81
82/*****************************************************************************
83 * Ethernet
84 ****************************************************************************/
85
86static struct mv643xx_eth_platform_data net2big_eth_data = {
87 .phy_addr = MV643XX_ETH_PHY_ADDR(8),
88};
89
90/*****************************************************************************
91 * I2C devices
92 ****************************************************************************/
93
94/*
95 * i2c addr | chip | description
96 * 0x32 | Ricoh 5C372b | RTC
97 * 0x50 | HT24LC08 | eeprom (1kB)
98 */
99static struct i2c_board_info __initdata net2big_i2c_devices[] = {
100 {
101 I2C_BOARD_INFO("rs5c372b", 0x32),
102 }, {
103 I2C_BOARD_INFO("24c08", 0x50),
104 },
105};
106
107/*****************************************************************************
108 * SATA
109 ****************************************************************************/
110
111static struct mv_sata_platform_data net2big_sata_data = {
112 .n_ports = 2,
113};
114
115#define NET2BIG_GPIO_SATA_POWER_REQ 19
116#define NET2BIG_GPIO_SATA0_POWER 23
117#define NET2BIG_GPIO_SATA1_POWER 25
118
119static void __init net2big_sata_power_init(void)
120{
121 int err;
122
123 /* Configure GPIOs over MPP max number. */
124 orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1);
125 orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1);
126
127 err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status");
128 if (err == 0) {
129 err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER);
130 if (err)
131 gpio_free(NET2BIG_GPIO_SATA0_POWER);
132 }
133 if (err) {
134 pr_err("net2big: failed to setup SATA0 power GPIO\n");
135 return;
136 }
137
138 err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status");
139 if (err == 0) {
140 err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER);
141 if (err)
142 gpio_free(NET2BIG_GPIO_SATA1_POWER);
143 }
144 if (err) {
145 pr_err("net2big: failed to setup SATA1 power GPIO\n");
146 goto err_free_1;
147 }
148
149 err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request");
150 if (err == 0) {
151 err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0);
152 if (err)
153 gpio_free(NET2BIG_GPIO_SATA_POWER_REQ);
154 }
155 if (err) {
156 pr_err("net2big: failed to setup SATA power request GPIO\n");
157 goto err_free_2;
158 }
159
160 if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) &&
161 gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) {
162 return;
163 }
164
165 /*
166 * SATA power up on both disk is done by pulling high the CPLD power
167 * request line. The 300ms delay is related to the CPLD clock and is
168 * needed to be sure that the CPLD has take into account the low line
169 * status.
170 */
171 msleep(300);
172 gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1);
173 pr_info("net2big: power up SATA hard disks\n");
174
175 return;
176
177err_free_2:
178 gpio_free(NET2BIG_GPIO_SATA1_POWER);
179err_free_1:
180 gpio_free(NET2BIG_GPIO_SATA0_POWER);
181
182 return;
183}
184
185/*****************************************************************************
186 * GPIO LEDs
187 ****************************************************************************/
188
189/*
190 * The power front LEDs (blue and red) and SATA red LEDs are controlled via a
191 * single GPIO line and are compatible with the leds-gpio driver.
192 *
193 * The SATA blue LEDs have some hardware blink capabilities which are detailled
194 * in the following array:
195 *
196 * SATAx blue LED | SATAx activity | LED state
197 * | |
198 * 0 | 0 | blink (rate 300ms)
199 * 1 | 0 | off
200 * ? | 1 | on
201 *
202 * Notes: The blue and the red front LED's can't be on at the same time.
203 * Blue LED have priority.
204 */
205
206#define NET2BIG_GPIO_PWR_RED_LED 6
207#define NET2BIG_GPIO_PWR_BLUE_LED 16
208#define NET2BIG_GPIO_PWR_LED_BLINK_STOP 7
209
210#define NET2BIG_GPIO_SATA0_RED_LED 11
211#define NET2BIG_GPIO_SATA1_RED_LED 10
212
213#define NET2BIG_GPIO_SATA0_BLUE_LED 17
214#define NET2BIG_GPIO_SATA1_BLUE_LED 13
215
216static struct gpio_led net2big_leds[] = {
217 {
218 .name = "net2big:red:power",
219 .gpio = NET2BIG_GPIO_PWR_RED_LED,
220 },
221 {
222 .name = "net2big:blue:power",
223 .gpio = NET2BIG_GPIO_PWR_BLUE_LED,
224 },
225 {
226 .name = "net2big:red:sata0",
227 .gpio = NET2BIG_GPIO_SATA0_RED_LED,
228 },
229 {
230 .name = "net2big:red:sata1",
231 .gpio = NET2BIG_GPIO_SATA1_RED_LED,
232 },
233};
234
235static struct gpio_led_platform_data net2big_led_data = {
236 .num_leds = ARRAY_SIZE(net2big_leds),
237 .leds = net2big_leds,
238};
239
240static struct platform_device net2big_gpio_leds = {
241 .name = "leds-gpio",
242 .id = -1,
243 .dev = {
244 .platform_data = &net2big_led_data,
245 },
246};
247
248static void __init net2big_gpio_leds_init(void)
249{
250 int err;
251
252 /* Stop initial CPLD slow red/blue blinking on power LED. */
253 err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP,
254 "Power LED blink stop");
255 if (err == 0) {
256 err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1);
257 if (err)
258 gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP);
259 }
260 if (err)
261 pr_err("net2big: failed to setup power LED blink GPIO\n");
262
263 /*
264 * Configure SATA0 and SATA1 blue LEDs to blink in relation with the
265 * hard disk activity.
266 */
267 err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED,
268 "SATA0 blue LED control");
269 if (err == 0) {
270 err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1);
271 if (err)
272 gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED);
273 }
274 if (err)
275 pr_err("net2big: failed to setup SATA0 blue LED GPIO\n");
276
277 err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED,
278 "SATA1 blue LED control");
279 if (err == 0) {
280 err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1);
281 if (err)
282 gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED);
283 }
284 if (err)
285 pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
286
287 platform_device_register(&net2big_gpio_leds);
288}
289
290/****************************************************************************
291 * GPIO keys
292 ****************************************************************************/
293
294#define NET2BIG_GPIO_PUSH_BUTTON 18
295#define NET2BIG_GPIO_POWER_SWITCH_ON 8
296#define NET2BIG_GPIO_POWER_SWITCH_OFF 9
297
298#define NET2BIG_SWITCH_POWER_ON 0x1
299#define NET2BIG_SWITCH_POWER_OFF 0x2
300
301static struct gpio_keys_button net2big_buttons[] = {
302 {
303 .type = EV_SW,
304 .code = NET2BIG_SWITCH_POWER_OFF,
305 .gpio = NET2BIG_GPIO_POWER_SWITCH_OFF,
306 .desc = "Power rocker switch (auto|off)",
307 .active_low = 0,
308 },
309 {
310 .type = EV_SW,
311 .code = NET2BIG_SWITCH_POWER_ON,
312 .gpio = NET2BIG_GPIO_POWER_SWITCH_ON,
313 .desc = "Power rocker switch (on|auto)",
314 .active_low = 0,
315 },
316 {
317 .type = EV_KEY,
318 .code = KEY_POWER,
319 .gpio = NET2BIG_GPIO_PUSH_BUTTON,
320 .desc = "Front Push Button",
321 .active_low = 0,
322 },
323};
324
325static struct gpio_keys_platform_data net2big_button_data = {
326 .buttons = net2big_buttons,
327 .nbuttons = ARRAY_SIZE(net2big_buttons),
328};
329
330static struct platform_device net2big_gpio_buttons = {
331 .name = "gpio-keys",
332 .id = -1,
333 .dev = {
334 .platform_data = &net2big_button_data,
335 },
336};
337
338/*****************************************************************************
339 * General Setup
340 ****************************************************************************/
341
342static struct orion5x_mpp_mode net2big_mpp_modes[] __initdata = {
343 { 0, MPP_GPIO }, /* Raid mode (bit 0) */
344 { 1, MPP_GPIO }, /* USB port 2 fuse (0 = Fail, 1 = Ok) */
345 { 2, MPP_GPIO }, /* Raid mode (bit 1) */
346 { 3, MPP_GPIO }, /* Board ID (bit 0) */
347 { 4, MPP_GPIO }, /* Fan activity (0 = Off, 1 = On) */
348 { 5, MPP_GPIO }, /* Fan fail detection */
349 { 6, MPP_GPIO }, /* Red front LED (0 = Off, 1 = On) */
350 { 7, MPP_GPIO }, /* Disable initial blinking on front LED */
351 { 8, MPP_GPIO }, /* Rear power switch (on|auto) */
352 { 9, MPP_GPIO }, /* Rear power switch (auto|off) */
353 { 10, MPP_GPIO }, /* SATA 1 red LED (0 = Off, 1 = On) */
354 { 11, MPP_GPIO }, /* SATA 0 red LED (0 = Off, 1 = On) */
355 { 12, MPP_GPIO }, /* Board ID (bit 1) */
356 { 13, MPP_GPIO }, /* SATA 1 blue LED blink control */
357 { 14, MPP_SATA_LED },
358 { 15, MPP_SATA_LED },
359 { 16, MPP_GPIO }, /* Blue front LED control */
360 { 17, MPP_GPIO }, /* SATA 0 blue LED blink control */
361 { 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */
362 { 19, MPP_GPIO }, /* SATA{0,1} power On/Off request */
363 { -1 }
364 /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
365 /* 23: SATA 0 power status */
366 /* 24: Board power off */
367 /* 25: SATA 1 power status */
368};
369
370#define NET2BIG_GPIO_POWER_OFF 24
371
372static void net2big_power_off(void)
373{
374 gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1);
375}
376
377static void __init net2big_init(void)
378{
379 /*
380 * Setup basic Orion functions. Need to be called early.
381 */
382 orion5x_init();
383
384 orion5x_mpp_conf(net2big_mpp_modes);
385
386 /*
387 * Configure peripherals.
388 */
389 orion5x_ehci0_init();
390 orion5x_ehci1_init();
391 orion5x_eth_init(&net2big_eth_data);
392 orion5x_i2c_init();
393 orion5x_uart0_init();
394 orion5x_xor_init();
395
396 net2big_sata_power_init();
397 orion5x_sata_init(&net2big_sata_data);
398
399 orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
400 NET2BIG_NOR_BOOT_SIZE);
401 platform_device_register(&net2big_nor_flash);
402
403 platform_device_register(&net2big_gpio_buttons);
404 net2big_gpio_leds_init();
405
406 i2c_register_board_info(0, net2big_i2c_devices,
407 ARRAY_SIZE(net2big_i2c_devices));
408
409 orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1);
410
411 if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
412 gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
413 pm_power_off = net2big_power_off;
414 else
415 pr_err("net2big: failed to configure power-off GPIO\n");
416
417 pr_notice("net2big: Flash writing is not yet supported.\n");
418}
419
420/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
421MACHINE_START(NET2BIG, "LaCie 2Big Network")
422 .phys_io = ORION5X_REGS_PHYS_BASE,
423 .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
424 .boot_params = 0x00000100,
425 .init_machine = net2big_init,
426 .map_io = orion5x_map_io,
427 .init_irq = orion5x_init_irq,
428 .timer = &orion5x_timer,
429 .fixup = tag_fixup_mem32,
430MACHINE_END
431
diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h
index 16eb02552d5d..a3449e35a6f5 100644
--- a/arch/arm/mach-pxa/include/mach/audio.h
+++ b/arch/arm/mach-pxa/include/mach/audio.h
@@ -3,10 +3,12 @@
3 3
4#include <sound/core.h> 4#include <sound/core.h>
5#include <sound/pcm.h> 5#include <sound/pcm.h>
6#include <sound/ac97_codec.h>
6 7
7/* 8/*
8 * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) 9 * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95)
9 * a -1 value means no gpio will be used for reset 10 * a -1 value means no gpio will be used for reset
11 * @codec_pdata: AC97 codec platform_data
10 12
11 * reset_gpio should only be specified for pxa27x CPUs where a silicon 13 * reset_gpio should only be specified for pxa27x CPUs where a silicon
12 * bug prevents correct operation of the reset line. If not specified, 14 * bug prevents correct operation of the reset line. If not specified,
@@ -20,6 +22,7 @@ typedef struct {
20 void (*resume)(void *); 22 void (*resume)(void *);
21 void *priv; 23 void *priv;
22 int reset_gpio; 24 int reset_gpio;
25 void *codec_pdata[AC97_BUS_MAX_DEVICES];
23} pxa2xx_audio_ops_t; 26} pxa2xx_audio_ops_t;
24 27
25extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); 28extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops);
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h b/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
index d5a48a96dea7..7b4eadc6df3a 100644
--- a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
+++ b/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
@@ -2,9 +2,12 @@
2#define __ASM_ARCH_PXA27x_KEYPAD_H 2#define __ASM_ARCH_PXA27x_KEYPAD_H
3 3
4#include <linux/input.h> 4#include <linux/input.h>
5#include <linux/input/matrix_keypad.h>
5 6
6#define MAX_MATRIX_KEY_ROWS (8) 7#define MAX_MATRIX_KEY_ROWS (8)
7#define MAX_MATRIX_KEY_COLS (8) 8#define MAX_MATRIX_KEY_COLS (8)
9#define MATRIX_ROW_SHIFT (3)
10#define MAX_DIRECT_KEY_NUM (8)
8 11
9/* pxa3xx keypad platform specific parameters 12/* pxa3xx keypad platform specific parameters
10 * 13 *
@@ -33,7 +36,7 @@ struct pxa27x_keypad_platform_data {
33 36
34 /* direct keys */ 37 /* direct keys */
35 int direct_key_num; 38 int direct_key_num;
36 unsigned int direct_key_map[8]; 39 unsigned int direct_key_map[MAX_DIRECT_KEY_NUM];
37 40
38 /* rotary encoders 0 */ 41 /* rotary encoders 0 */
39 int enable_rotary0; 42 int enable_rotary0;
@@ -51,8 +54,6 @@ struct pxa27x_keypad_platform_data {
51 unsigned int debounce_interval; 54 unsigned int debounce_interval;
52}; 55};
53 56
54#define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val))
55
56extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info); 57extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
57 58
58#endif /* __ASM_ARCH_PXA27x_KEYPAD_H */ 59#endif /* __ASM_ARCH_PXA27x_KEYPAD_H */
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 2546c066cd6e..629e05d1196e 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -678,8 +678,8 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
678 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); 678 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
679 } 679 }
680 680
681 if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) ) 681 if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) ||
682 { 682 (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) {
683 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); 683 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
684 corgi_goto_sleep(alarm_time, alarm_enable, state); 684 corgi_goto_sleep(alarm_time, alarm_enable, state);
685 return 1; 685 return 1;
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index d4cfa2145386..dfc9b0bc6eb2 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -75,7 +75,7 @@ config MACH_REALVIEW_PBX
75 75
76config REALVIEW_HIGH_PHYS_OFFSET 76config REALVIEW_HIGH_PHYS_OFFSET
77 bool "High physical base address for the RealView platform" 77 bool "High physical base address for the RealView platform"
78 depends on !MACH_REALVIEW_PB1176 78 depends on MMU && !MACH_REALVIEW_PB1176
79 default y 79 default y
80 help 80 help
81 RealView boards other than PB1176 have the RAM available at 81 RealView boards other than PB1176 have the RAM available at
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index facbd49eec67..dc3519c50ab2 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -221,6 +221,9 @@ arch_initcall(realview_i2c_init);
221 221
222#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET) 222#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
223 223
224/*
225 * This is only used if GPIOLIB support is disabled
226 */
224static unsigned int realview_mmc_status(struct device *dev) 227static unsigned int realview_mmc_status(struct device *dev)
225{ 228{
226 struct amba_device *adev = container_of(dev, struct amba_device, dev); 229 struct amba_device *adev = container_of(dev, struct amba_device, dev);
@@ -237,11 +240,15 @@ static unsigned int realview_mmc_status(struct device *dev)
237struct mmc_platform_data realview_mmc0_plat_data = { 240struct mmc_platform_data realview_mmc0_plat_data = {
238 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 241 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
239 .status = realview_mmc_status, 242 .status = realview_mmc_status,
243 .gpio_wp = 17,
244 .gpio_cd = 16,
240}; 245};
241 246
242struct mmc_platform_data realview_mmc1_plat_data = { 247struct mmc_platform_data realview_mmc1_plat_data = {
243 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 248 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
244 .status = realview_mmc_status, 249 .status = realview_mmc_status,
250 .gpio_wp = 19,
251 .gpio_cd = 18,
245}; 252};
246 253
247/* 254/*
diff --git a/arch/arm/mach-realview/include/mach/gpio.h b/arch/arm/mach-realview/include/mach/gpio.h
new file mode 100644
index 000000000000..94ff27678a46
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/gpio.h
@@ -0,0 +1,6 @@
1#include <asm-generic/gpio.h>
2
3#define gpio_get_value __gpio_get_value
4#define gpio_set_value __gpio_set_value
5#define gpio_cansleep __gpio_cansleep
6#define gpio_to_irq __gpio_to_irq
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
index b42c14f89acb..8a638d15797f 100644
--- a/arch/arm/mach-realview/include/mach/hardware.h
+++ b/arch/arm/mach-realview/include/mach/hardware.h
@@ -25,6 +25,7 @@
25#include <asm/sizes.h> 25#include <asm/sizes.h>
26 26
27/* macro to get at IO space when running virtually */ 27/* macro to get at IO space when running virtually */
28#ifdef CONFIG_MMU
28/* 29/*
29 * Statically mapped addresses: 30 * Statically mapped addresses:
30 * 31 *
@@ -33,6 +34,9 @@
33 * 1fxx xxxx -> fexx xxxx 34 * 1fxx xxxx -> fexx xxxx
34 */ 35 */
35#define IO_ADDRESS(x) (((x) & 0x03ffffff) + 0xfb000000) 36#define IO_ADDRESS(x) (((x) & 0x03ffffff) + 0xfb000000)
37#else
38#define IO_ADDRESS(x) (x)
39#endif
36#define __io_address(n) __io(IO_ADDRESS(n)) 40#define __io_address(n) __io(IO_ADDRESS(n))
37 41
38#endif 42#endif
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index ac0e83f1cc3a..a88458b4799d 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -20,6 +20,7 @@
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/localtimer.h> 22#include <asm/localtimer.h>
23#include <asm/unified.h>
23 24
24#include <mach/board-eb.h> 25#include <mach/board-eb.h>
25#include <mach/board-pb11mp.h> 26#include <mach/board-pb11mp.h>
@@ -137,26 +138,19 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
137 138
138static void __init poke_milo(void) 139static void __init poke_milo(void)
139{ 140{
140 extern void secondary_startup(void);
141
142 /* nobody is to be released from the pen yet */ 141 /* nobody is to be released from the pen yet */
143 pen_release = -1; 142 pen_release = -1;
144 143
145 /* 144 /*
146 * write the address of secondary startup into the system-wide 145 * Write the address of secondary startup into the system-wide flags
147 * flags register, then clear the bottom two bits, which is what 146 * register. The BootMonitor waits for this register to become
148 * BootMonitor is waiting for 147 * non-zero.
149 */ 148 */
150#if 1
151#define REALVIEW_SYS_FLAGSS_OFFSET 0x30 149#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
152 __raw_writel(virt_to_phys(realview_secondary_startup),
153 __io_address(REALVIEW_SYS_BASE) +
154 REALVIEW_SYS_FLAGSS_OFFSET);
155#define REALVIEW_SYS_FLAGSC_OFFSET 0x34 150#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
156 __raw_writel(3, 151 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
157 __io_address(REALVIEW_SYS_BASE) + 152 __io_address(REALVIEW_SYS_BASE) +
158 REALVIEW_SYS_FLAGSC_OFFSET); 153 REALVIEW_SYS_FLAGSS_OFFSET);
159#endif
160 154
161 mb(); 155 mb();
162} 156}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 8dfa44e08a94..abd13b448671 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/sysdev.h> 24#include <linux/sysdev.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h>
26#include <linux/io.h> 27#include <linux/io.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -113,6 +114,21 @@ static void __init realview_eb_map_io(void)
113 iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc)); 114 iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc));
114} 115}
115 116
117static struct pl061_platform_data gpio0_plat_data = {
118 .gpio_base = 0,
119 .irq_base = -1,
120};
121
122static struct pl061_platform_data gpio1_plat_data = {
123 .gpio_base = 8,
124 .irq_base = -1,
125};
126
127static struct pl061_platform_data gpio2_plat_data = {
128 .gpio_base = 16,
129 .irq_base = -1,
130};
131
116/* 132/*
117 * RealView EB AMBA devices 133 * RealView EB AMBA devices
118 */ 134 */
@@ -189,9 +205,9 @@ AMBA_DEVICE(clcd, "dev:20", EB_CLCD, &clcd_plat_data);
189AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); 205AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
190AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); 206AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
191AMBA_DEVICE(wdog, "dev:e1", EB_WATCHDOG, NULL); 207AMBA_DEVICE(wdog, "dev:e1", EB_WATCHDOG, NULL);
192AMBA_DEVICE(gpio0, "dev:e4", EB_GPIO0, NULL); 208AMBA_DEVICE(gpio0, "dev:e4", EB_GPIO0, &gpio0_plat_data);
193AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); 209AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
194AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); 210AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
195AMBA_DEVICE(rtc, "dev:e8", EB_RTC, NULL); 211AMBA_DEVICE(rtc, "dev:e8", EB_RTC, NULL);
196AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); 212AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
197AMBA_DEVICE(uart0, "dev:f1", EB_UART0, NULL); 213AMBA_DEVICE(uart0, "dev:f1", EB_UART0, NULL);
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 25efe71a67c7..17fbb0e889b6 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/sysdev.h> 24#include <linux/sysdev.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h>
26#include <linux/io.h> 27#include <linux/io.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -107,6 +108,21 @@ static void __init realview_pb1176_map_io(void)
107 iotable_init(realview_pb1176_io_desc, ARRAY_SIZE(realview_pb1176_io_desc)); 108 iotable_init(realview_pb1176_io_desc, ARRAY_SIZE(realview_pb1176_io_desc));
108} 109}
109 110
111static struct pl061_platform_data gpio0_plat_data = {
112 .gpio_base = 0,
113 .irq_base = -1,
114};
115
116static struct pl061_platform_data gpio1_plat_data = {
117 .gpio_base = 8,
118 .irq_base = -1,
119};
120
121static struct pl061_platform_data gpio2_plat_data = {
122 .gpio_base = 16,
123 .irq_base = -1,
124};
125
110/* 126/*
111 * RealView PB1176 AMBA devices 127 * RealView PB1176 AMBA devices
112 */ 128 */
@@ -164,9 +180,9 @@ AMBA_DEVICE(uart3, "fpga:09", PB1176_UART3, NULL);
164AMBA_DEVICE(smc, "dev:00", PB1176_SMC, NULL); 180AMBA_DEVICE(smc, "dev:00", PB1176_SMC, NULL);
165AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); 181AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
166AMBA_DEVICE(wdog, "dev:e1", PB1176_WATCHDOG, NULL); 182AMBA_DEVICE(wdog, "dev:e1", PB1176_WATCHDOG, NULL);
167AMBA_DEVICE(gpio0, "dev:e4", PB1176_GPIO0, NULL); 183AMBA_DEVICE(gpio0, "dev:e4", PB1176_GPIO0, &gpio0_plat_data);
168AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); 184AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
169AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); 185AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
170AMBA_DEVICE(rtc, "dev:e8", PB1176_RTC, NULL); 186AMBA_DEVICE(rtc, "dev:e8", PB1176_RTC, NULL);
171AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); 187AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
172AMBA_DEVICE(uart0, "dev:f1", PB1176_UART0, NULL); 188AMBA_DEVICE(uart0, "dev:f1", PB1176_UART0, NULL);
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index dc4b16943907..fdd042b85f40 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/sysdev.h> 24#include <linux/sysdev.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h>
26#include <linux/io.h> 27#include <linux/io.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -108,6 +109,21 @@ static void __init realview_pb11mp_map_io(void)
108 iotable_init(realview_pb11mp_io_desc, ARRAY_SIZE(realview_pb11mp_io_desc)); 109 iotable_init(realview_pb11mp_io_desc, ARRAY_SIZE(realview_pb11mp_io_desc));
109} 110}
110 111
112static struct pl061_platform_data gpio0_plat_data = {
113 .gpio_base = 0,
114 .irq_base = -1,
115};
116
117static struct pl061_platform_data gpio1_plat_data = {
118 .gpio_base = 8,
119 .irq_base = -1,
120};
121
122static struct pl061_platform_data gpio2_plat_data = {
123 .gpio_base = 16,
124 .irq_base = -1,
125};
126
111/* 127/*
112 * RealView PB11MPCore AMBA devices 128 * RealView PB11MPCore AMBA devices
113 */ 129 */
@@ -166,9 +182,9 @@ AMBA_DEVICE(uart3, "fpga:09", PB11MP_UART3, NULL);
166AMBA_DEVICE(smc, "dev:00", PB11MP_SMC, NULL); 182AMBA_DEVICE(smc, "dev:00", PB11MP_SMC, NULL);
167AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); 183AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
168AMBA_DEVICE(wdog, "dev:e1", PB11MP_WATCHDOG, NULL); 184AMBA_DEVICE(wdog, "dev:e1", PB11MP_WATCHDOG, NULL);
169AMBA_DEVICE(gpio0, "dev:e4", PB11MP_GPIO0, NULL); 185AMBA_DEVICE(gpio0, "dev:e4", PB11MP_GPIO0, &gpio0_plat_data);
170AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); 186AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
171AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); 187AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
172AMBA_DEVICE(rtc, "dev:e8", PB11MP_RTC, NULL); 188AMBA_DEVICE(rtc, "dev:e8", PB11MP_RTC, NULL);
173AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); 189AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
174AMBA_DEVICE(uart0, "dev:f1", PB11MP_UART0, NULL); 190AMBA_DEVICE(uart0, "dev:f1", PB11MP_UART0, NULL);
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index d6ac1eb86576..70bba9900d97 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/sysdev.h> 24#include <linux/sysdev.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h>
26#include <linux/io.h> 27#include <linux/io.h>
27 28
28#include <asm/irq.h> 29#include <asm/irq.h>
@@ -98,6 +99,21 @@ static void __init realview_pba8_map_io(void)
98 iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc)); 99 iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc));
99} 100}
100 101
102static struct pl061_platform_data gpio0_plat_data = {
103 .gpio_base = 0,
104 .irq_base = -1,
105};
106
107static struct pl061_platform_data gpio1_plat_data = {
108 .gpio_base = 8,
109 .irq_base = -1,
110};
111
112static struct pl061_platform_data gpio2_plat_data = {
113 .gpio_base = 16,
114 .irq_base = -1,
115};
116
101/* 117/*
102 * RealView PBA8Core AMBA devices 118 * RealView PBA8Core AMBA devices
103 */ 119 */
@@ -156,9 +172,9 @@ AMBA_DEVICE(uart3, "fpga:09", PBA8_UART3, NULL);
156AMBA_DEVICE(smc, "dev:00", PBA8_SMC, NULL); 172AMBA_DEVICE(smc, "dev:00", PBA8_SMC, NULL);
157AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); 173AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
158AMBA_DEVICE(wdog, "dev:e1", PBA8_WATCHDOG, NULL); 174AMBA_DEVICE(wdog, "dev:e1", PBA8_WATCHDOG, NULL);
159AMBA_DEVICE(gpio0, "dev:e4", PBA8_GPIO0, NULL); 175AMBA_DEVICE(gpio0, "dev:e4", PBA8_GPIO0, &gpio0_plat_data);
160AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); 176AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
161AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); 177AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
162AMBA_DEVICE(rtc, "dev:e8", PBA8_RTC, NULL); 178AMBA_DEVICE(rtc, "dev:e8", PBA8_RTC, NULL);
163AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); 179AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
164AMBA_DEVICE(uart0, "dev:f1", PBA8_UART0, NULL); 180AMBA_DEVICE(uart0, "dev:f1", PBA8_UART0, NULL);
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index ede2a57240a3..ce6c5d25fbef 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -22,6 +22,7 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/sysdev.h> 23#include <linux/sysdev.h>
24#include <linux/amba/bus.h> 24#include <linux/amba/bus.h>
25#include <linux/amba/pl061.h>
25#include <linux/io.h> 26#include <linux/io.h>
26 27
27#include <asm/irq.h> 28#include <asm/irq.h>
@@ -118,6 +119,21 @@ static void __init realview_pbx_map_io(void)
118 iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc)); 119 iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc));
119} 120}
120 121
122static struct pl061_platform_data gpio0_plat_data = {
123 .gpio_base = 0,
124 .irq_base = -1,
125};
126
127static struct pl061_platform_data gpio1_plat_data = {
128 .gpio_base = 8,
129 .irq_base = -1,
130};
131
132static struct pl061_platform_data gpio2_plat_data = {
133 .gpio_base = 16,
134 .irq_base = -1,
135};
136
121/* 137/*
122 * RealView PBXCore AMBA devices 138 * RealView PBXCore AMBA devices
123 */ 139 */
@@ -176,9 +192,9 @@ AMBA_DEVICE(uart3, "fpga:09", PBX_UART3, NULL);
176AMBA_DEVICE(smc, "dev:00", PBX_SMC, NULL); 192AMBA_DEVICE(smc, "dev:00", PBX_SMC, NULL);
177AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); 193AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
178AMBA_DEVICE(wdog, "dev:e1", PBX_WATCHDOG, NULL); 194AMBA_DEVICE(wdog, "dev:e1", PBX_WATCHDOG, NULL);
179AMBA_DEVICE(gpio0, "dev:e4", PBX_GPIO0, NULL); 195AMBA_DEVICE(gpio0, "dev:e4", PBX_GPIO0, &gpio0_plat_data);
180AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); 196AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
181AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); 197AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
182AMBA_DEVICE(rtc, "dev:e8", PBX_RTC, NULL); 198AMBA_DEVICE(rtc, "dev:e8", PBX_RTC, NULL);
183AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); 199AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
184AMBA_DEVICE(uart0, "dev:f1", PBX_UART0, NULL); 200AMBA_DEVICE(uart0, "dev:f1", PBX_UART0, NULL);
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 41bb65d5b91f..d8c023d4df30 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -12,6 +12,7 @@ config CPU_S3C2410
12 select S3C2410_GPIO 12 select S3C2410_GPIO
13 select CPU_LLSERIAL_S3C2410 13 select CPU_LLSERIAL_S3C2410
14 select S3C2410_PM if PM 14 select S3C2410_PM if PM
15 select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
15 help 16 help
16 Support for S3C2410 and S3C2410A family from the S3C24XX line 17 Support for S3C2410 and S3C2410A family from the S3C24XX line
17 of Samsung Mobile CPUs. 18 of Samsung Mobile CPUs.
@@ -45,6 +46,22 @@ config MACH_BAST_IDE
45 Internal node for machines with an BAST style IDE 46 Internal node for machines with an BAST style IDE
46 interface 47 interface
47 48
49# cpu frequency scaling support
50
51config S3C2410_CPUFREQ
52 bool
53 depends on CPU_FREQ_S3C24XX && CPU_S3C2410
54 select S3C2410_CPUFREQ_UTILS
55 help
56 CPU Frequency scaling support for S3C2410
57
58config S3C2410_PLLTABLE
59 bool
60 depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL
61 default y
62 help
63 Select the PLL table for the S3C2410
64
48menu "S3C2410 Machines" 65menu "S3C2410 Machines"
49 66
50config ARCH_SMDK2410 67config ARCH_SMDK2410
@@ -79,6 +96,7 @@ config MACH_N30
79config ARCH_BAST 96config ARCH_BAST
80 bool "Simtec Electronics BAST (EB2410ITX)" 97 bool "Simtec Electronics BAST (EB2410ITX)"
81 select CPU_S3C2410 98 select CPU_S3C2410
99 select S3C2410_IOTIMING if S3C2410_CPUFREQ
82 select PM_SIMTEC if PM 100 select PM_SIMTEC if PM
83 select SIMTEC_NOR 101 select SIMTEC_NOR
84 select MACH_BAST_IDE 102 select MACH_BAST_IDE
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index fca02f82711c..2ab5ba4b266f 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
15obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o 15obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
16obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o 16obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o
17obj-$(CONFIG_S3C2410_GPIO) += gpio.o 17obj-$(CONFIG_S3C2410_GPIO) += gpio.o
18obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o
19obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o
18 20
19# Machine support 21# Machine support
20 22
diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c
new file mode 100644
index 000000000000..9d1186877d08
--- /dev/null
+++ b/arch/arm/mach-s3c2410/cpu-freq.c
@@ -0,0 +1,159 @@
1/* linux/arch/arm/mach-s3c2410/cpu-freq.c
2 *
3 * Copyright (c) 2006,2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C2410 CPU Frequency scaling
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/cpufreq.h>
19#include <linux/sysdev.h>
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <linux/io.h>
23
24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
26
27#include <mach/regs-clock.h>
28
29#include <plat/cpu.h>
30#include <plat/clock.h>
31#include <plat/cpu-freq-core.h>
32
33/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
34
35static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
36{
37 u32 clkdiv = 0;
38
39 if (cfg->divs.h_divisor == 2)
40 clkdiv |= S3C2410_CLKDIVN_HDIVN;
41
42 if (cfg->divs.p_divisor != cfg->divs.h_divisor)
43 clkdiv |= S3C2410_CLKDIVN_PDIVN;
44
45 __raw_writel(clkdiv, S3C2410_CLKDIVN);
46}
47
48static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
49{
50 unsigned long hclk, fclk, pclk;
51 unsigned int hdiv, pdiv;
52 unsigned long hclk_max;
53
54 fclk = cfg->freq.fclk;
55 hclk_max = cfg->max.hclk;
56
57 cfg->freq.armclk = fclk;
58
59 s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n",
60 __func__, fclk, hclk_max);
61
62 hdiv = (fclk > cfg->max.hclk) ? 2 : 1;
63 hclk = fclk / hdiv;
64
65 if (hclk > cfg->max.hclk) {
66 s3c_freq_dbg("%s: hclk too big\n", __func__);
67 return -EINVAL;
68 }
69
70 pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
71 pclk = hclk / pdiv;
72
73 if (pclk > cfg->max.pclk) {
74 s3c_freq_dbg("%s: pclk too big\n", __func__);
75 return -EINVAL;
76 }
77
78 pdiv *= hdiv;
79
80 /* record the result */
81 cfg->divs.p_divisor = pdiv;
82 cfg->divs.h_divisor = hdiv;
83
84 return 0 ;
85}
86
87static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
88 .max = {
89 .fclk = 200000000,
90 .hclk = 100000000,
91 .pclk = 50000000,
92 },
93
94 /* transition latency is about 5ms worst-case, so
95 * set 10ms to be sure */
96 .latency = 10000000,
97
98 .locktime_m = 150,
99 .locktime_u = 150,
100 .locktime_bits = 12,
101
102 .need_pll = 1,
103
104 .name = "s3c2410",
105 .calc_iotiming = s3c2410_iotiming_calc,
106 .set_iotiming = s3c2410_iotiming_set,
107 .get_iotiming = s3c2410_iotiming_get,
108 .resume_clocks = s3c2410_setup_clocks,
109
110 .set_fvco = s3c2410_set_fvco,
111 .set_refresh = s3c2410_cpufreq_setrefresh,
112 .set_divs = s3c2410_cpufreq_setdivs,
113 .calc_divs = s3c2410_cpufreq_calcdivs,
114
115 .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
116};
117
118static int s3c2410_cpufreq_add(struct sys_device *sysdev)
119{
120 return s3c_cpufreq_register(&s3c2410_cpufreq_info);
121}
122
123static struct sysdev_driver s3c2410_cpufreq_driver = {
124 .add = s3c2410_cpufreq_add,
125};
126
127static int __init s3c2410_cpufreq_init(void)
128{
129 return sysdev_driver_register(&s3c2410_sysclass,
130 &s3c2410_cpufreq_driver);
131}
132
133arch_initcall(s3c2410_cpufreq_init);
134
135static int s3c2410a_cpufreq_add(struct sys_device *sysdev)
136{
137 /* alter the maximum freq settings for S3C2410A. If a board knows
138 * it only has a maximum of 200, then it should register its own
139 * limits. */
140
141 s3c2410_cpufreq_info.max.fclk = 266000000;
142 s3c2410_cpufreq_info.max.hclk = 133000000;
143 s3c2410_cpufreq_info.max.pclk = 66500000;
144 s3c2410_cpufreq_info.name = "s3c2410a";
145
146 return s3c2410_cpufreq_add(sysdev);
147}
148
149static struct sysdev_driver s3c2410a_cpufreq_driver = {
150 .add = s3c2410a_cpufreq_add,
151};
152
153static int __init s3c2410a_cpufreq_init(void)
154{
155 return sysdev_driver_register(&s3c2410a_sysclass,
156 &s3c2410a_cpufreq_driver);
157}
158
159arch_initcall(s3c2410a_cpufreq_init);
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index dbf96e60d992..63b753f56c64 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -164,6 +164,17 @@ static int __init s3c2410_dma_drvinit(void)
164} 164}
165 165
166arch_initcall(s3c2410_dma_drvinit); 166arch_initcall(s3c2410_dma_drvinit);
167
168static struct sysdev_driver s3c2410a_dma_driver = {
169 .add = s3c2410_dma_add,
170};
171
172static int __init s3c2410a_dma_drvinit(void)
173{
174 return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_dma_driver);
175}
176
177arch_initcall(s3c2410a_dma_drvinit);
167#endif 178#endif
168 179
169#if defined(CONFIG_CPU_S3C2442) 180#if defined(CONFIG_CPU_S3C2442)
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 2a2384ffa7b1..6c12c6312ad8 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -164,6 +164,12 @@
164#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 164#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3
165#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 165#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3
166 166
167#ifdef CONFIG_CPU_S3C2440
168#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
169#else
170#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97
171#endif
172
167/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ 173/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
168#define FIQ_START IRQ_EINT0 174#define FIQ_START IRQ_EINT0
169 175
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index e99b212cb1ca..b049e61460b6 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -67,6 +67,13 @@
67#define S3C2443_PA_HSMMC (0x4A800000) 67#define S3C2443_PA_HSMMC (0x4A800000)
68#define S3C2443_SZ_HSMMC (256) 68#define S3C2443_SZ_HSMMC (256)
69 69
70/* S3C2412 memory and IO controls */
71#define S3C2412_PA_SSMC (0x4F000000)
72#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000)
73
74#define S3C2412_PA_EBI (0x48800000)
75#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000)
76
70/* physical addresses of all the chip-select areas */ 77/* physical addresses of all the chip-select areas */
71 78
72#define S3C2410_CS0 (0x00000000) 79#define S3C2410_CS0 (0x00000000)
@@ -103,5 +110,6 @@
103#define S3C_PA_UART S3C24XX_PA_UART 110#define S3C_PA_UART S3C24XX_PA_UART
104#define S3C_PA_USBHOST S3C2410_PA_USBHOST 111#define S3C_PA_USBHOST S3C2410_PA_USBHOST
105#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC 112#define S3C_PA_HSMMC0 S3C2443_PA_HSMMC
113#define S3C_PA_NAND S3C24XX_PA_NAND
106 114
107#endif /* __ASM_ARCH_MAP_H */ 115#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index b278d0c45ccf..f6e8eec879c8 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -328,13 +328,15 @@
328 328
329#define S3C2410_GPD8_VD16 (0x02 << 16) 329#define S3C2410_GPD8_VD16 (0x02 << 16)
330#define S3C2400_GPD8_TOUT3 (0x02 << 16) 330#define S3C2400_GPD8_TOUT3 (0x02 << 16)
331#define S3C2440_GPD8_SPIMISO1 (0x03 << 16)
331 332
332#define S3C2410_GPD9_VD17 (0x02 << 18) 333#define S3C2410_GPD9_VD17 (0x02 << 18)
333#define S3C2400_GPD9_TCLK0 (0x02 << 18) 334#define S3C2400_GPD9_TCLK0 (0x02 << 18)
334#define S3C2410_GPD9_MASK (0x03 << 18) 335#define S3C2440_GPD9_SPIMOSI1 (0x03 << 18)
335 336
336#define S3C2410_GPD10_VD18 (0x02 << 20) 337#define S3C2410_GPD10_VD18 (0x02 << 20)
337#define S3C2400_GPD10_nWAIT (0x02 << 20) 338#define S3C2400_GPD10_nWAIT (0x02 << 20)
339#define S3C2440_GPD10_SPICLK1 (0x03 << 20)
338 340
339#define S3C2410_GPD11_VD19 (0x02 << 22) 341#define S3C2410_GPD11_VD19 (0x02 << 22)
340 342
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
index 57759804e2fa..7f7c52947963 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
@@ -73,6 +73,16 @@
73#define S3C2410_BWSCON_WS7 (1<<30) 73#define S3C2410_BWSCON_WS7 (1<<30)
74#define S3C2410_BWSCON_ST7 (1<<31) 74#define S3C2410_BWSCON_ST7 (1<<31)
75 75
76/* accesor functions for getting BANK(n) configuration. (n != 0) */
77
78#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
79
80#define S3C2410_BWSCON_DW8 (0)
81#define S3C2410_BWSCON_DW16 (1)
82#define S3C2410_BWSCON_DW32 (2)
83#define S3C2410_BWSCON_WS (1 << 2)
84#define S3C2410_BWSCON_ST (1 << 3)
85
76/* memory set (rom, ram) */ 86/* memory set (rom, ram) */
77#define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004) 87#define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004)
78#define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008) 88#define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
index a4bf27123170..fb6352515090 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
@@ -14,9 +14,11 @@
14#ifndef __ASM_ARM_REGS_S3C2412_MEM 14#ifndef __ASM_ARM_REGS_S3C2412_MEM
15#define __ASM_ARM_REGS_S3C2412_MEM 15#define __ASM_ARM_REGS_S3C2412_MEM
16 16
17#ifndef S3C2412_MEMREG
18#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) 17#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
19#endif 18#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
19
20#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x))
21#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o)))
20 22
21#define S3C2412_BANKCFG S3C2412_MEMREG(0x00) 23#define S3C2412_BANKCFG S3C2412_MEMREG(0x00)
22#define S3C2412_BANKCON1 S3C2412_MEMREG(0x04) 24#define S3C2412_BANKCON1 S3C2412_MEMREG(0x04)
@@ -26,4 +28,21 @@
26#define S3C2412_REFRESH S3C2412_MEMREG(0x10) 28#define S3C2412_REFRESH S3C2412_MEMREG(0x10)
27#define S3C2412_TIMEOUT S3C2412_MEMREG(0x14) 29#define S3C2412_TIMEOUT S3C2412_MEMREG(0x14)
28 30
31/* EBI control registers */
32
33#define S3C2412_EBI_PR S3C2412_EBIREG(0x00)
34#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x04)
35
36/* SSMC control registers */
37
38#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x00)
39#define S3C2412_SMIDCYR(x) S3C2412_SSMC(x, 0x00)
40#define S3C2412_SMBWSTRD(x) S3C2412_SSMC(x, 0x04)
41#define S3C2412_SMBWSTWRR(x) S3C2412_SSMC(x, 0x08)
42#define S3C2412_SMBWSTOENR(x) S3C2412_SSMC(x, 0x0C)
43#define S3C2412_SMBWSTWENR(x) S3C2412_SSMC(x, 0x10)
44#define S3C2412_SMBCR(x) S3C2412_SSMC(x, 0x14)
45#define S3C2412_SMBSR(x) S3C2412_SSMC(x, 0x18)
46#define S3C2412_SMBWSTBRDR(x) S3C2412_SSMC(x, 0x1C)
47
29#endif /* __ASM_ARM_REGS_S3C2412_MEM */ 48#endif /* __ASM_ARM_REGS_S3C2412_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h
index 1d300fb112b1..193b39d654ed 100644
--- a/arch/arm/mach-s3c2410/include/mach/spi.h
+++ b/arch/arm/mach-s3c2410/include/mach/spi.h
@@ -30,4 +30,7 @@ extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
30extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, 30extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
31 int enable); 31 int enable);
32 32
33extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
34 int enable);
35
33#endif /* __ASM_ARCH_SPI_H */ 36#endif /* __ASM_ARCH_SPI_H */
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 92150399563b..5e2f35332056 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -39,9 +39,22 @@ static struct sysdev_driver s3c2410_irq_driver = {
39 .resume = s3c24xx_irq_resume, 39 .resume = s3c24xx_irq_resume,
40}; 40};
41 41
42static int s3c2410_irq_init(void) 42static int __init s3c2410_irq_init(void)
43{ 43{
44 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); 44 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
45} 45}
46 46
47arch_initcall(s3c2410_irq_init); 47arch_initcall(s3c2410_irq_init);
48
49static struct sysdev_driver s3c2410a_irq_driver = {
50 .add = s3c2410_irq_add,
51 .suspend = s3c24xx_irq_suspend,
52 .resume = s3c24xx_irq_resume,
53};
54
55static int __init s3c2410a_irq_init(void)
56{
57 return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver);
58}
59
60arch_initcall(s3c2410a_irq_init);
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index ce3baba2cd7f..647c9adb018f 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -45,6 +45,7 @@
45#include <mach/regs-mem.h> 45#include <mach/regs-mem.h>
46#include <mach/regs-lcd.h> 46#include <mach/regs-lcd.h>
47 47
48#include <plat/hwmon.h>
48#include <plat/nand.h> 49#include <plat/nand.h>
49#include <plat/iic.h> 50#include <plat/iic.h>
50#include <mach/fb.h> 51#include <mach/fb.h>
@@ -59,6 +60,7 @@
59#include <plat/clock.h> 60#include <plat/clock.h>
60#include <plat/devs.h> 61#include <plat/devs.h>
61#include <plat/cpu.h> 62#include <plat/cpu.h>
63#include <plat/cpu-freq.h>
62 64
63#include "usb-simtec.h" 65#include "usb-simtec.h"
64#include "nor-simtec.h" 66#include "nor-simtec.h"
@@ -547,7 +549,35 @@ static struct i2c_board_info bast_i2c_devs[] __initdata = {
547 }, 549 },
548}; 550};
549 551
552static struct s3c_hwmon_pdata bast_hwmon_info = {
553 /* LCD contrast (0-6.6V) */
554 .in[0] = &(struct s3c_hwmon_chcfg) {
555 .name = "lcd-contrast",
556 .mult = 3300,
557 .div = 512,
558 },
559 /* LED current feedback */
560 .in[1] = &(struct s3c_hwmon_chcfg) {
561 .name = "led-feedback",
562 .mult = 3300,
563 .div = 1024,
564 },
565 /* LCD feedback (0-6.6V) */
566 .in[2] = &(struct s3c_hwmon_chcfg) {
567 .name = "lcd-feedback",
568 .mult = 3300,
569 .div = 512,
570 },
571 /* Vcore (1.8-2.0V), Vref 3.3V */
572 .in[3] = &(struct s3c_hwmon_chcfg) {
573 .name = "vcore",
574 .mult = 3300,
575 .div = 1024,
576 },
577};
578
550/* Standard BAST devices */ 579/* Standard BAST devices */
580// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
551 581
552static struct platform_device *bast_devices[] __initdata = { 582static struct platform_device *bast_devices[] __initdata = {
553 &s3c_device_usb, 583 &s3c_device_usb,
@@ -556,6 +586,8 @@ static struct platform_device *bast_devices[] __initdata = {
556 &s3c_device_i2c0, 586 &s3c_device_i2c0,
557 &s3c_device_rtc, 587 &s3c_device_rtc,
558 &s3c_device_nand, 588 &s3c_device_nand,
589 &s3c_device_adc,
590 &s3c_device_hwmon,
559 &bast_device_dm9k, 591 &bast_device_dm9k,
560 &bast_device_asix, 592 &bast_device_asix,
561 &bast_device_axpp, 593 &bast_device_axpp,
@@ -570,6 +602,12 @@ static struct clk *bast_clocks[] __initdata = {
570 &s3c24xx_uclk, 602 &s3c24xx_uclk,
571}; 603};
572 604
605static struct s3c_cpufreq_board __initdata bast_cpufreq = {
606 .refresh = 7800, /* 7.8usec */
607 .auto_io = 1,
608 .need_io = 1,
609};
610
573static void __init bast_map_io(void) 611static void __init bast_map_io(void)
574{ 612{
575 /* initialise the clocks */ 613 /* initialise the clocks */
@@ -588,6 +626,7 @@ static void __init bast_map_io(void)
588 s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); 626 s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
589 627
590 s3c_device_nand.dev.platform_data = &bast_nand_info; 628 s3c_device_nand.dev.platform_data = &bast_nand_info;
629 s3c_device_hwmon.dev.platform_data = &bast_hwmon_info;
591 630
592 s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); 631 s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
593 s3c24xx_init_clocks(0); 632 s3c24xx_init_clocks(0);
@@ -608,6 +647,8 @@ static void __init bast_init(void)
608 647
609 usb_simtec_init(); 648 usb_simtec_init();
610 nor_simtec_init(); 649 nor_simtec_init();
650
651 s3c_cpufreq_setboard(&bast_cpufreq);
611} 652}
612 653
613MACHINE_START(BAST, "Simtec-BAST") 654MACHINE_START(BAST, "Simtec-BAST")
diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c
new file mode 100644
index 000000000000..f178c2fd9d85
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pll.c
@@ -0,0 +1,95 @@
1/* arch/arm/mach-s3c2410/pll.c
2 *
3 * Copyright (c) 2006,2007 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 * Vincent Sanders <vince@arm.linux.org.uk>
7 *
8 * S3C2410 CPU PLL tables
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25#include <linux/types.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/sysdev.h>
29#include <linux/list.h>
30#include <linux/clk.h>
31#include <linux/err.h>
32
33#include <plat/cpu.h>
34#include <plat/cpu-freq-core.h>
35
36static struct cpufreq_frequency_table pll_vals_12MHz[] = {
37 { .frequency = 34000000, .index = PLLVAL(82, 2, 3), },
38 { .frequency = 45000000, .index = PLLVAL(82, 1, 3), },
39 { .frequency = 51000000, .index = PLLVAL(161, 3, 3), },
40 { .frequency = 48000000, .index = PLLVAL(120, 2, 3), },
41 { .frequency = 56000000, .index = PLLVAL(142, 2, 3), },
42 { .frequency = 68000000, .index = PLLVAL(82, 2, 2), },
43 { .frequency = 79000000, .index = PLLVAL(71, 1, 2), },
44 { .frequency = 85000000, .index = PLLVAL(105, 2, 2), },
45 { .frequency = 90000000, .index = PLLVAL(112, 2, 2), },
46 { .frequency = 101000000, .index = PLLVAL(127, 2, 2), },
47 { .frequency = 113000000, .index = PLLVAL(105, 1, 2), },
48 { .frequency = 118000000, .index = PLLVAL(150, 2, 2), },
49 { .frequency = 124000000, .index = PLLVAL(116, 1, 2), },
50 { .frequency = 135000000, .index = PLLVAL(82, 2, 1), },
51 { .frequency = 147000000, .index = PLLVAL(90, 2, 1), },
52 { .frequency = 152000000, .index = PLLVAL(68, 1, 1), },
53 { .frequency = 158000000, .index = PLLVAL(71, 1, 1), },
54 { .frequency = 170000000, .index = PLLVAL(77, 1, 1), },
55 { .frequency = 180000000, .index = PLLVAL(82, 1, 1), },
56 { .frequency = 186000000, .index = PLLVAL(85, 1, 1), },
57 { .frequency = 192000000, .index = PLLVAL(88, 1, 1), },
58 { .frequency = 203000000, .index = PLLVAL(161, 3, 1), },
59
60 /* 2410A extras */
61
62 { .frequency = 210000000, .index = PLLVAL(132, 2, 1), },
63 { .frequency = 226000000, .index = PLLVAL(105, 1, 1), },
64 { .frequency = 266000000, .index = PLLVAL(125, 1, 1), },
65 { .frequency = 268000000, .index = PLLVAL(126, 1, 1), },
66 { .frequency = 270000000, .index = PLLVAL(127, 1, 1), },
67};
68
69static int s3c2410_plls_add(struct sys_device *dev)
70{
71 return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
72}
73
74static struct sysdev_driver s3c2410_plls_drv = {
75 .add = s3c2410_plls_add,
76};
77
78static int __init s3c2410_pll_init(void)
79{
80 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_plls_drv);
81
82}
83
84arch_initcall(s3c2410_pll_init);
85
86static struct sysdev_driver s3c2410a_plls_drv = {
87 .add = s3c2410_plls_add,
88};
89
90static int __init s3c2410a_pll_init(void)
91{
92 return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_plls_drv);
93}
94
95arch_initcall(s3c2410a_pll_init);
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index 143e08a599d4..966119c8efee 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -119,6 +119,18 @@ static int __init s3c2410_pm_drvinit(void)
119} 119}
120 120
121arch_initcall(s3c2410_pm_drvinit); 121arch_initcall(s3c2410_pm_drvinit);
122
123static struct sysdev_driver s3c2410a_pm_driver = {
124 .add = s3c2410_pm_add,
125 .resume = s3c2410_pm_resume,
126};
127
128static int __init s3c2410a_pm_drvinit(void)
129{
130 return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_pm_driver);
131}
132
133arch_initcall(s3c2410a_pm_drvinit);
122#endif 134#endif
123 135
124#if defined(CONFIG_CPU_S3C2440) 136#if defined(CONFIG_CPU_S3C2440)
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index feb141b1f915..91ba42f688ac 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -105,17 +105,33 @@ void __init_or_cpufreq s3c2410_setup_clocks(void)
105 s3c24xx_setup_clocks(fclk, hclk, pclk); 105 s3c24xx_setup_clocks(fclk, hclk, pclk);
106} 106}
107 107
108/* fake ARMCLK for use with cpufreq, etc. */
109
110static struct clk s3c2410_armclk = {
111 .name = "armclk",
112 .parent = &clk_f,
113 .id = -1,
114};
115
108void __init s3c2410_init_clocks(int xtal) 116void __init s3c2410_init_clocks(int xtal)
109{ 117{
110 s3c24xx_register_baseclocks(xtal); 118 s3c24xx_register_baseclocks(xtal);
111 s3c2410_setup_clocks(); 119 s3c2410_setup_clocks();
112 s3c2410_baseclk_add(); 120 s3c2410_baseclk_add();
121 s3c24xx_register_clock(&s3c2410_armclk);
113} 122}
114 123
115struct sysdev_class s3c2410_sysclass = { 124struct sysdev_class s3c2410_sysclass = {
116 .name = "s3c2410-core", 125 .name = "s3c2410-core",
117}; 126};
118 127
128/* Note, we would have liked to name this s3c2410-core, but we cannot
129 * register two sysdev_class with the same name.
130 */
131struct sysdev_class s3c2410a_sysclass = {
132 .name = "s3c2410a-core",
133};
134
119static struct sys_device s3c2410_sysdev = { 135static struct sys_device s3c2410_sysdev = {
120 .cls = &s3c2410_sysclass, 136 .cls = &s3c2410_sysclass,
121}; 137};
@@ -133,9 +149,22 @@ static int __init s3c2410_core_init(void)
133 149
134core_initcall(s3c2410_core_init); 150core_initcall(s3c2410_core_init);
135 151
152static int __init s3c2410a_core_init(void)
153{
154 return sysdev_class_register(&s3c2410a_sysclass);
155}
156
157core_initcall(s3c2410a_core_init);
158
136int __init s3c2410_init(void) 159int __init s3c2410_init(void)
137{ 160{
138 printk("S3C2410: Initialising architecture\n"); 161 printk("S3C2410: Initialising architecture\n");
139 162
140 return sysdev_register(&s3c2410_sysdev); 163 return sysdev_register(&s3c2410_sysdev);
141} 164}
165
166int __init s3c2410a_init(void)
167{
168 s3c2410_sysdev.cls = &s3c2410a_sysclass;
169 return s3c2410_init();
170}
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 63586ffd0ae7..35c1bde89cf2 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -32,6 +32,15 @@ config S3C2412_PM
32 help 32 help
33 Internal config node to apply S3C2412 power management 33 Internal config node to apply S3C2412 power management
34 34
35# Note, the S3C2412 IOtiming support is in plat-s3c24xx
36
37config S3C2412_CPUFREQ
38 bool
39 depends on CPU_FREQ_S3C24XX && CPU_S3C2412
40 select S3C2412_IOTIMING
41 default y
42 help
43 CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
35 44
36menu "S3C2412 Machines" 45menu "S3C2412 Machines"
37 46
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index 20918d5dc6a9..530ec46cbaea 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_S3C2412) += clock.o
15obj-$(CONFIG_CPU_S3C2412) += gpio.o 15obj-$(CONFIG_CPU_S3C2412) += gpio.o
16obj-$(CONFIG_S3C2412_DMA) += dma.o 16obj-$(CONFIG_S3C2412_DMA) += dma.o
17obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o 17obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o
18obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o
18 19
19# Machine support 20# Machine support
20 21
diff --git a/arch/arm/mach-s3c2412/cpu-freq.c b/arch/arm/mach-s3c2412/cpu-freq.c
new file mode 100644
index 000000000000..eb3ea1721335
--- /dev/null
+++ b/arch/arm/mach-s3c2412/cpu-freq.c
@@ -0,0 +1,257 @@
1/* linux/arch/arm/mach-s3c2412/cpu-freq.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C2412 CPU Frequency scalling
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/cpufreq.h>
19#include <linux/sysdev.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/err.h>
23#include <linux/io.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27
28#include <mach/regs-clock.h>
29#include <mach/regs-s3c2412-mem.h>
30
31#include <plat/cpu.h>
32#include <plat/clock.h>
33#include <plat/cpu-freq-core.h>
34
35/* our clock resources. */
36static struct clk *xtal;
37static struct clk *fclk;
38static struct clk *hclk;
39static struct clk *armclk;
40
41/* HDIV: 1, 2, 3, 4, 6, 8 */
42
43static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
44{
45 unsigned int hdiv, pdiv, armdiv, dvs;
46 unsigned long hclk, fclk, armclk, armdiv_clk;
47 unsigned long hclk_max;
48
49 fclk = cfg->freq.fclk;
50 armclk = cfg->freq.armclk;
51 hclk_max = cfg->max.hclk;
52
53 /* We can't run hclk above armclk as at the best we have to
54 * have armclk and hclk in dvs mode. */
55
56 if (hclk_max > armclk)
57 hclk_max = armclk;
58
59 s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n",
60 __func__, fclk, armclk, hclk_max);
61 s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n",
62 __func__, cfg->freq.fclk, cfg->freq.armclk,
63 cfg->freq.hclk, cfg->freq.pclk);
64
65 armdiv = fclk / armclk;
66
67 if (armdiv < 1)
68 armdiv = 1;
69 if (armdiv > 2)
70 armdiv = 2;
71
72 cfg->divs.arm_divisor = armdiv;
73 armdiv_clk = fclk / armdiv;
74
75 hdiv = armdiv_clk / hclk_max;
76 if (hdiv < 1)
77 hdiv = 1;
78
79 cfg->freq.hclk = hclk = armdiv_clk / hdiv;
80
81 /* set dvs depending on whether we reached armclk or not. */
82 cfg->divs.dvs = dvs = armclk < armdiv_clk;
83
84 /* update the actual armclk we achieved. */
85 cfg->freq.armclk = dvs ? hclk : armdiv_clk;
86
87 s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n",
88 __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs);
89
90 if (hdiv > 4)
91 goto invalid;
92
93 pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
94
95 if ((hclk / pdiv) > cfg->max.pclk)
96 pdiv++;
97
98 cfg->freq.pclk = hclk / pdiv;
99
100 s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
101
102 if (pdiv > 2)
103 goto invalid;
104
105 pdiv *= hdiv;
106
107 /* store the result, and then return */
108
109 cfg->divs.h_divisor = hdiv * armdiv;
110 cfg->divs.p_divisor = pdiv * armdiv;
111
112 return 0;
113
114 invalid:
115 return -EINVAL;
116}
117
118static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
119{
120 unsigned long clkdiv;
121 unsigned long olddiv;
122
123 olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN);
124
125 /* clear off current clock info */
126
127 clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN;
128 clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK;
129 clkdiv &= ~S3C2412_CLKDIVN_PDIVN;
130
131 if (cfg->divs.arm_divisor == 2)
132 clkdiv |= S3C2412_CLKDIVN_ARMDIVN;
133
134 clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1);
135
136 if (cfg->divs.p_divisor != cfg->divs.h_divisor)
137 clkdiv |= S3C2412_CLKDIVN_PDIVN;
138
139 s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv);
140 __raw_writel(clkdiv, S3C2410_CLKDIVN);
141
142 clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
143}
144
145static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
146{
147 struct s3c_cpufreq_board *board = cfg->board;
148 unsigned long refresh;
149
150 s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__,
151 board->refresh, cfg->freq.hclk);
152
153 /* Reduce both the refresh time (in ns) and the frequency (in MHz)
154 * by 10 each to ensure that we do not overflow 32 bit numbers. This
155 * should work for HCLK up to 133MHz and refresh period up to 30usec.
156 */
157
158 refresh = (board->refresh / 10);
159 refresh *= (cfg->freq.hclk / 100);
160 refresh /= (1 * 1000 * 1000); /* 10^6 */
161
162 s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh);
163 __raw_writel(refresh, S3C2412_REFRESH);
164}
165
166/* set the default cpu frequency information, based on an 200MHz part
167 * as we have no other way of detecting the speed rating in software.
168 */
169
170static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
171 .max = {
172 .fclk = 200000000,
173 .hclk = 100000000,
174 .pclk = 50000000,
175 },
176
177 .latency = 5000000, /* 5ms */
178
179 .locktime_m = 150,
180 .locktime_u = 150,
181 .locktime_bits = 16,
182
183 .name = "s3c2412",
184 .set_refresh = s3c2412_cpufreq_setrefresh,
185 .set_divs = s3c2412_cpufreq_setdivs,
186 .calc_divs = s3c2412_cpufreq_calcdivs,
187
188 .calc_iotiming = s3c2412_iotiming_calc,
189 .set_iotiming = s3c2412_iotiming_set,
190 .get_iotiming = s3c2412_iotiming_get,
191
192 .resume_clocks = s3c2412_setup_clocks,
193
194 .debug_io_show = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
195};
196
197static int s3c2412_cpufreq_add(struct sys_device *sysdev)
198{
199 unsigned long fclk_rate;
200
201 hclk = clk_get(NULL, "hclk");
202 if (IS_ERR(hclk)) {
203 printk(KERN_ERR "%s: cannot find hclk clock\n", __func__);
204 return -ENOENT;
205 }
206
207 fclk = clk_get(NULL, "fclk");
208 if (IS_ERR(fclk)) {
209 printk(KERN_ERR "%s: cannot find fclk clock\n", __func__);
210 goto err_fclk;
211 }
212
213 fclk_rate = clk_get_rate(fclk);
214 if (fclk_rate > 200000000) {
215 printk(KERN_INFO
216 "%s: fclk %ld MHz, assuming 266MHz capable part\n",
217 __func__, fclk_rate / 1000000);
218 s3c2412_cpufreq_info.max.fclk = 266000000;
219 s3c2412_cpufreq_info.max.hclk = 133000000;
220 s3c2412_cpufreq_info.max.pclk = 66000000;
221 }
222
223 armclk = clk_get(NULL, "armclk");
224 if (IS_ERR(armclk)) {
225 printk(KERN_ERR "%s: cannot find arm clock\n", __func__);
226 goto err_armclk;
227 }
228
229 xtal = clk_get(NULL, "xtal");
230 if (IS_ERR(xtal)) {
231 printk(KERN_ERR "%s: cannot find xtal clock\n", __func__);
232 goto err_xtal;
233 }
234
235 return s3c_cpufreq_register(&s3c2412_cpufreq_info);
236
237err_xtal:
238 clk_put(armclk);
239err_armclk:
240 clk_put(fclk);
241err_fclk:
242 clk_put(hclk);
243
244 return -ENOENT;
245}
246
247static struct sysdev_driver s3c2412_cpufreq_driver = {
248 .add = s3c2412_cpufreq_add,
249};
250
251static int s3c2412_cpufreq_init(void)
252{
253 return sysdev_driver_register(&s3c2412_sysclass,
254 &s3c2412_cpufreq_driver);
255}
256
257arch_initcall(s3c2412_cpufreq_init);
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index 5b5aba69ec3f..bef39f77729d 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -69,6 +69,18 @@ static struct map_desc s3c2412_iodesc[] __initdata = {
69 IODESC_ENT(CLKPWR), 69 IODESC_ENT(CLKPWR),
70 IODESC_ENT(TIMER), 70 IODESC_ENT(TIMER),
71 IODESC_ENT(WATCHDOG), 71 IODESC_ENT(WATCHDOG),
72 {
73 .virtual = (unsigned long)S3C2412_VA_SSMC,
74 .pfn = __phys_to_pfn(S3C2412_PA_SSMC),
75 .length = SZ_1M,
76 .type = MT_DEVICE,
77 },
78 {
79 .virtual = (unsigned long)S3C2412_VA_EBI,
80 .pfn = __phys_to_pfn(S3C2412_PA_EBI),
81 .length = SZ_1M,
82 .type = MT_DEVICE,
83 },
72}; 84};
73 85
74/* uart registration process */ 86/* uart registration process */
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 8cfeaec37306..8ae1b288f7fa 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -33,6 +33,7 @@ config MACH_ANUBIS
33 select PM_SIMTEC if PM 33 select PM_SIMTEC if PM
34 select HAVE_PATA_PLATFORM 34 select HAVE_PATA_PLATFORM
35 select S3C24XX_GPIO_EXTRA64 35 select S3C24XX_GPIO_EXTRA64
36 select S3C2440_XTAL_12000000
36 select S3C_DEV_USB_HOST 37 select S3C_DEV_USB_HOST
37 help 38 help
38 Say Y here if you are using the Simtec Electronics ANUBIS 39 Say Y here if you are using the Simtec Electronics ANUBIS
@@ -44,6 +45,8 @@ config MACH_OSIRIS
44 select S3C24XX_DCLK 45 select S3C24XX_DCLK
45 select PM_SIMTEC if PM 46 select PM_SIMTEC if PM
46 select S3C24XX_GPIO_EXTRA128 47 select S3C24XX_GPIO_EXTRA128
48 select S3C2440_XTAL_12000000
49 select S3C2410_IOTIMING if S3C2440_CPUFREQ
47 select S3C_DEV_USB_HOST 50 select S3C_DEV_USB_HOST
48 help 51 help
49 Say Y here if you are using the Simtec IM2440D20 module, also 52 Say Y here if you are using the Simtec IM2440D20 module, also
@@ -52,6 +55,7 @@ config MACH_OSIRIS
52config MACH_RX3715 55config MACH_RX3715
53 bool "HP iPAQ rx3715" 56 bool "HP iPAQ rx3715"
54 select CPU_S3C2440 57 select CPU_S3C2440
58 select S3C2440_XTAL_16934400
55 select PM_H1940 if PM 59 select PM_H1940 if PM
56 help 60 help
57 Say Y here if you are using the HP iPAQ rx3715. 61 Say Y here if you are using the HP iPAQ rx3715.
@@ -59,6 +63,7 @@ config MACH_RX3715
59config ARCH_S3C2440 63config ARCH_S3C2440
60 bool "SMDK2440" 64 bool "SMDK2440"
61 select CPU_S3C2440 65 select CPU_S3C2440
66 select S3C2440_XTAL_16934400
62 select MACH_SMDK 67 select MACH_SMDK
63 select S3C_DEV_USB_HOST 68 select S3C_DEV_USB_HOST
64 help 69 help
@@ -67,6 +72,7 @@ config ARCH_S3C2440
67config MACH_NEXCODER_2440 72config MACH_NEXCODER_2440
68 bool "NexVision NEXCODER 2440 Light Board" 73 bool "NexVision NEXCODER 2440 Light Board"
69 select CPU_S3C2440 74 select CPU_S3C2440
75 select S3C2440_XTAL_12000000
70 select S3C_DEV_USB_HOST 76 select S3C_DEV_USB_HOST
71 help 77 help
72 Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board 78 Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
@@ -75,6 +81,7 @@ config SMDK2440_CPU2440
75 bool "SMDK2440 with S3C2440 CPU module" 81 bool "SMDK2440 with S3C2440 CPU module"
76 depends on ARCH_S3C2440 82 depends on ARCH_S3C2440
77 default y if ARCH_S3C2440 83 default y if ARCH_S3C2440
84 select S3C2440_XTAL_16934400
78 select CPU_S3C2440 85 select CPU_S3C2440
79 86
80config MACH_AT2440EVB 87config MACH_AT2440EVB
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index cba064b49a64..2105a41281a4 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -34,6 +34,7 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/mach-types.h> 35#include <asm/mach-types.h>
36 36
37#include <plat/cpu-freq.h>
37#include <plat/regs-serial.h> 38#include <plat/regs-serial.h>
38#include <mach/regs-gpio.h> 39#include <mach/regs-gpio.h>
39#include <mach/regs-mem.h> 40#include <mach/regs-mem.h>
@@ -351,6 +352,12 @@ static struct clk *osiris_clocks[] __initdata = {
351 &s3c24xx_uclk, 352 &s3c24xx_uclk,
352}; 353};
353 354
355static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
356 .refresh = 7800, /* refresh period is 7.8usec */
357 .auto_io = 1,
358 .need_io = 1,
359};
360
354static void __init osiris_map_io(void) 361static void __init osiris_map_io(void)
355{ 362{
356 unsigned long flags; 363 unsigned long flags;
@@ -402,6 +409,8 @@ static void __init osiris_init(void)
402 409
403 s3c_i2c0_set_platdata(NULL); 410 s3c_i2c0_set_platdata(NULL);
404 411
412 s3c_cpufreq_setboard(&osiris_cpufreq);
413
405 i2c_register_board_info(0, osiris_i2c_devs, 414 i2c_register_board_info(0, osiris_i2c_devs,
406 ARRAY_SIZE(osiris_i2c_devs)); 415 ARRAY_SIZE(osiris_i2c_devs));
407 416
diff --git a/arch/arm/mach-s3c24a0/include/mach/map.h b/arch/arm/mach-s3c24a0/include/mach/map.h
index a01132717e34..79e4d93ea2b6 100644
--- a/arch/arm/mach-s3c24a0/include/mach/map.h
+++ b/arch/arm/mach-s3c24a0/include/mach/map.h
@@ -81,5 +81,6 @@
81 81
82#define S3C_PA_UART S3C24A0_PA_UART 82#define S3C_PA_UART S3C24A0_PA_UART
83#define S3C_PA_IIC S3C24A0_PA_IIC 83#define S3C_PA_IIC S3C24A0_PA_IIC
84#define S3C_PA_NAND S3C24XX_PA_NAND
84 85
85#endif /* __ASM_ARCH_24A0_MAP_H */ 86#endif /* __ASM_ARCH_24A0_MAP_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h
index 5057d9948d35..fc8b223bad4f 100644
--- a/arch/arm/mach-s3c6400/include/mach/map.h
+++ b/arch/arm/mach-s3c6400/include/mach/map.h
@@ -38,18 +38,21 @@
38#define S3C_VA_UART2 S3C_VA_UARTx(2) 38#define S3C_VA_UART2 S3C_VA_UARTx(2)
39#define S3C_VA_UART3 S3C_VA_UARTx(3) 39#define S3C_VA_UART3 S3C_VA_UARTx(3)
40 40
41#define S3C64XX_PA_NAND (0x70200000)
41#define S3C64XX_PA_FB (0x77100000) 42#define S3C64XX_PA_FB (0x77100000)
42#define S3C64XX_PA_USB_HSOTG (0x7C000000) 43#define S3C64XX_PA_USB_HSOTG (0x7C000000)
43#define S3C64XX_PA_WATCHDOG (0x7E004000) 44#define S3C64XX_PA_WATCHDOG (0x7E004000)
44#define S3C64XX_PA_SYSCON (0x7E00F000) 45#define S3C64XX_PA_SYSCON (0x7E00F000)
46#define S3C64XX_PA_AC97 (0x7F001000)
45#define S3C64XX_PA_IIS0 (0x7F002000) 47#define S3C64XX_PA_IIS0 (0x7F002000)
46#define S3C64XX_PA_IIS1 (0x7F003000) 48#define S3C64XX_PA_IIS1 (0x7F003000)
47#define S3C64XX_PA_TIMER (0x7F006000) 49#define S3C64XX_PA_TIMER (0x7F006000)
48#define S3C64XX_PA_IIC0 (0x7F004000) 50#define S3C64XX_PA_IIC0 (0x7F004000)
51#define S3C64XX_PA_IISV4 (0x7F00D000)
49#define S3C64XX_PA_IIC1 (0x7F00F000) 52#define S3C64XX_PA_IIC1 (0x7F00F000)
50 53
51#define S3C64XX_PA_GPIO (0x7F008000) 54#define S3C64XX_PA_GPIO (0x7F008000)
52#define S3C64XX_VA_GPIO S3C_ADDR(0x00500000) 55#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000)
53#define S3C64XX_SZ_GPIO SZ_4K 56#define S3C64XX_SZ_GPIO SZ_4K
54 57
55#define S3C64XX_PA_SDRAM (0x50000000) 58#define S3C64XX_PA_SDRAM (0x50000000)
@@ -57,7 +60,7 @@
57#define S3C64XX_PA_VIC1 (0x71300000) 60#define S3C64XX_PA_VIC1 (0x71300000)
58 61
59#define S3C64XX_PA_MODEM (0x74108000) 62#define S3C64XX_PA_MODEM (0x74108000)
60#define S3C64XX_VA_MODEM S3C_ADDR(0x00600000) 63#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000)
61 64
62#define S3C64XX_PA_USBHOST (0x74300000) 65#define S3C64XX_PA_USBHOST (0x74300000)
63 66
@@ -72,6 +75,7 @@
72#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2 75#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2
73#define S3C_PA_IIC S3C64XX_PA_IIC0 76#define S3C_PA_IIC S3C64XX_PA_IIC0
74#define S3C_PA_IIC1 S3C64XX_PA_IIC1 77#define S3C_PA_IIC1 S3C64XX_PA_IIC1
78#define S3C_PA_NAND S3C64XX_PA_NAND
75#define S3C_PA_FB S3C64XX_PA_FB 79#define S3C_PA_FB S3C64XX_PA_FB
76#define S3C_PA_USBHOST S3C64XX_PA_USBHOST 80#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
77#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG 81#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
diff --git a/arch/arm/mach-s3c6400/s3c6400.c b/arch/arm/mach-s3c6400/s3c6400.c
index 1ece887d90bb..b42bdd0f2138 100644
--- a/arch/arm/mach-s3c6400/s3c6400.c
+++ b/arch/arm/mach-s3c6400/s3c6400.c
@@ -48,6 +48,8 @@ void __init s3c6400_map_io(void)
48 48
49 /* the i2c devices are directly compatible with s3c2440 */ 49 /* the i2c devices are directly compatible with s3c2440 */
50 s3c_i2c0_setname("s3c2440-i2c"); 50 s3c_i2c0_setname("s3c2440-i2c");
51
52 s3c_device_nand.name = "s3c6400-nand";
51} 53}
52 54
53void __init s3c6400_init_clocks(int xtal) 55void __init s3c6400_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig
index e63aac7f4e5a..f9d0f09f9761 100644
--- a/arch/arm/mach-s3c6410/Kconfig
+++ b/arch/arm/mach-s3c6410/Kconfig
@@ -97,3 +97,13 @@ config MACH_NCP
97 select S3C64XX_SETUP_I2C1 97 select S3C64XX_SETUP_I2C1
98 help 98 help
99 Machine support for the Samsung NCP 99 Machine support for the Samsung NCP
100
101config MACH_HMT
102 bool "Airgoo HMT"
103 select CPU_S3C6410
104 select S3C_DEV_FB
105 select S3C_DEV_USB_HOST
106 select S3C64XX_SETUP_FB_24BPP
107 select HAVE_PWM
108 help
109 Machine support for the Airgoo HMT
diff --git a/arch/arm/mach-s3c6410/Makefile b/arch/arm/mach-s3c6410/Makefile
index 6f9deac88612..3e48c3dbf973 100644
--- a/arch/arm/mach-s3c6410/Makefile
+++ b/arch/arm/mach-s3c6410/Makefile
@@ -23,5 +23,4 @@ obj-$(CONFIG_S3C6410_SETUP_SDHCI) += setup-sdhci.o
23obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o 23obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
24obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o 24obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
25obj-$(CONFIG_MACH_NCP) += mach-ncp.o 25obj-$(CONFIG_MACH_NCP) += mach-ncp.o
26 26obj-$(CONFIG_MACH_HMT) += mach-hmt.o
27
diff --git a/arch/arm/mach-s3c6410/cpu.c b/arch/arm/mach-s3c6410/cpu.c
index ade904de8895..9b67c663d9d8 100644
--- a/arch/arm/mach-s3c6410/cpu.c
+++ b/arch/arm/mach-s3c6410/cpu.c
@@ -62,6 +62,8 @@ void __init s3c6410_map_io(void)
62 /* the i2c devices are directly compatible with s3c2440 */ 62 /* the i2c devices are directly compatible with s3c2440 */
63 s3c_i2c0_setname("s3c2440-i2c"); 63 s3c_i2c0_setname("s3c2440-i2c");
64 s3c_i2c1_setname("s3c2440-i2c"); 64 s3c_i2c1_setname("s3c2440-i2c");
65
66 s3c_device_nand.name = "s3c6400-nand";
65} 67}
66 68
67void __init s3c6410_init_clocks(int xtal) 69void __init s3c6410_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c6410/mach-hmt.c b/arch/arm/mach-s3c6410/mach-hmt.c
new file mode 100644
index 000000000000..c5741056193f
--- /dev/null
+++ b/arch/arm/mach-s3c6410/mach-hmt.c
@@ -0,0 +1,276 @@
1/* mach-hmt.c - Platform code for Airgoo HMT
2 *
3 * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9*/
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/serial_core.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/i2c.h>
17#include <linux/fb.h>
18#include <linux/gpio.h>
19#include <linux/delay.h>
20#include <linux/leds.h>
21#include <linux/pwm_backlight.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/irq.h>
28
29#include <mach/hardware.h>
30#include <mach/regs-fb.h>
31#include <mach/map.h>
32
33#include <asm/irq.h>
34#include <asm/mach-types.h>
35
36#include <plat/regs-serial.h>
37#include <plat/iic.h>
38#include <plat/fb.h>
39#include <plat/nand.h>
40
41#include <plat/s3c6410.h>
42#include <plat/clock.h>
43#include <plat/devs.h>
44#include <plat/cpu.h>
45
46#define UCON S3C2410_UCON_DEFAULT
47#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
48#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
49
50static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
51 [0] = {
52 .hwport = 0,
53 .flags = 0,
54 .ucon = UCON,
55 .ulcon = ULCON,
56 .ufcon = UFCON,
57 },
58 [1] = {
59 .hwport = 1,
60 .flags = 0,
61 .ucon = UCON,
62 .ulcon = ULCON,
63 .ufcon = UFCON,
64 },
65 [2] = {
66 .hwport = 2,
67 .flags = 0,
68 .ucon = UCON,
69 .ulcon = ULCON,
70 .ufcon = UFCON,
71 },
72};
73
74static int hmt_bl_init(struct device *dev)
75{
76 int ret;
77
78 ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
79 if (!ret)
80 ret = gpio_direction_output(S3C64XX_GPB(4), 0);
81
82 return ret;
83}
84
85static int hmt_bl_notify(int brightness)
86{
87 /*
88 * translate from CIELUV/CIELAB L*->brightness, E.G. from
89 * perceived luminance to light output. Assumes range 0..25600
90 */
91 if (brightness < 0x800) {
92 /* Y = Yn * L / 903.3 */
93 brightness = (100*256 * brightness + 231245/2) / 231245;
94 } else {
95 /* Y = Yn * ((L + 16) / 116 )^3 */
96 int t = (brightness*4 + 16*1024 + 58)/116;
97 brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
98 }
99
100 gpio_set_value(S3C64XX_GPB(4), brightness);
101
102 return brightness;
103}
104
105static void hmt_bl_exit(struct device *dev)
106{
107 gpio_free(S3C64XX_GPB(4));
108}
109
110static struct platform_pwm_backlight_data hmt_backlight_data = {
111 .pwm_id = 1,
112 .max_brightness = 100 * 256,
113 .dft_brightness = 40 * 256,
114 .pwm_period_ns = 1000000000 / (100 * 256 * 20),
115 .init = hmt_bl_init,
116 .notify = hmt_bl_notify,
117 .exit = hmt_bl_exit,
118
119};
120
121static struct platform_device hmt_backlight_device = {
122 .name = "pwm-backlight",
123 .dev = {
124 .parent = &s3c_device_timer[1].dev,
125 .platform_data = &hmt_backlight_data,
126 },
127};
128
129static struct s3c_fb_pd_win hmt_fb_win0 = {
130 .win_mode = {
131 .pixclock = 41094,
132 .left_margin = 8,
133 .right_margin = 13,
134 .upper_margin = 7,
135 .lower_margin = 5,
136 .hsync_len = 3,
137 .vsync_len = 1,
138 .xres = 800,
139 .yres = 480,
140 },
141 .max_bpp = 32,
142 .default_bpp = 16,
143};
144
145/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
146static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
147 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
148 .win[0] = &hmt_fb_win0,
149 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
150 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
151};
152
153static struct mtd_partition hmt_nand_part[] = {
154 [0] = {
155 .name = "uboot",
156 .size = SZ_512K,
157 .offset = 0,
158 },
159 [1] = {
160 .name = "uboot-env1",
161 .size = SZ_256K,
162 .offset = SZ_512K,
163 },
164 [2] = {
165 .name = "uboot-env2",
166 .size = SZ_256K,
167 .offset = SZ_512K + SZ_256K,
168 },
169 [3] = {
170 .name = "kernel",
171 .size = SZ_2M,
172 .offset = SZ_1M,
173 },
174 [4] = {
175 .name = "rootfs",
176 .size = MTDPART_SIZ_FULL,
177 .offset = SZ_1M + SZ_2M,
178 },
179};
180
181static struct s3c2410_nand_set hmt_nand_sets[] = {
182 [0] = {
183 .name = "nand",
184 .nr_chips = 1,
185 .nr_partitions = ARRAY_SIZE(hmt_nand_part),
186 .partitions = hmt_nand_part,
187 },
188};
189
190static struct s3c2410_platform_nand hmt_nand_info = {
191 .tacls = 25,
192 .twrph0 = 55,
193 .twrph1 = 40,
194 .nr_sets = ARRAY_SIZE(hmt_nand_sets),
195 .sets = hmt_nand_sets,
196};
197
198static struct gpio_led hmt_leds[] = {
199 { /* left function keys */
200 .name = "left:blue",
201 .gpio = S3C64XX_GPO(12),
202 .default_trigger = "default-on",
203 },
204 { /* right function keys - red */
205 .name = "right:red",
206 .gpio = S3C64XX_GPO(13),
207 },
208 { /* right function keys - green */
209 .name = "right:green",
210 .gpio = S3C64XX_GPO(14),
211 },
212 { /* right function keys - blue */
213 .name = "right:blue",
214 .gpio = S3C64XX_GPO(15),
215 .default_trigger = "default-on",
216 },
217};
218
219static struct gpio_led_platform_data hmt_led_data = {
220 .num_leds = ARRAY_SIZE(hmt_leds),
221 .leds = hmt_leds,
222};
223
224static struct platform_device hmt_leds_device = {
225 .name = "leds-gpio",
226 .id = -1,
227 .dev.platform_data = &hmt_led_data,
228};
229
230static struct map_desc hmt_iodesc[] = {};
231
232static struct platform_device *hmt_devices[] __initdata = {
233 &s3c_device_i2c0,
234 &s3c_device_nand,
235 &s3c_device_fb,
236 &s3c_device_usb,
237 &s3c_device_timer[1],
238 &hmt_backlight_device,
239 &hmt_leds_device,
240};
241
242static void __init hmt_map_io(void)
243{
244 s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
245 s3c24xx_init_clocks(12000000);
246 s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
247}
248
249static void __init hmt_machine_init(void)
250{
251 s3c_i2c0_set_platdata(NULL);
252 s3c_fb_set_platdata(&hmt_lcd_pdata);
253 s3c_device_nand.dev.platform_data = &hmt_nand_info;
254
255 gpio_request(S3C64XX_GPC(7), "usb power");
256 gpio_direction_output(S3C64XX_GPC(7), 0);
257 gpio_request(S3C64XX_GPM(0), "usb power");
258 gpio_direction_output(S3C64XX_GPM(0), 1);
259 gpio_request(S3C64XX_GPK(7), "usb power");
260 gpio_direction_output(S3C64XX_GPK(7), 1);
261 gpio_request(S3C64XX_GPF(13), "usb power");
262 gpio_direction_output(S3C64XX_GPF(13), 1);
263
264 platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
265}
266
267MACHINE_START(HMT, "Airgoo-HMT")
268 /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
269 .phys_io = S3C_PA_UART & 0xfff00000,
270 .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
271 .boot_params = S3C64XX_PA_SDRAM + 0x100,
272 .init_irq = s3c6410_init_irq,
273 .map_io = hmt_map_io,
274 .init_machine = hmt_machine_init,
275 .timer = &s3c24xx_timer,
276MACHINE_END
diff --git a/arch/arm/mach-s3c6410/mach-ncp.c b/arch/arm/mach-s3c6410/mach-ncp.c
index 6030636f8548..55e9bbfaf68b 100644
--- a/arch/arm/mach-s3c6410/mach-ncp.c
+++ b/arch/arm/mach-s3c6410/mach-ncp.c
@@ -79,7 +79,7 @@ static struct platform_device *ncp_devices[] __initdata = {
79 &s3c_device_i2c0, 79 &s3c_device_i2c0,
80}; 80};
81 81
82struct map_desc ncp_iodesc[] = {}; 82static struct map_desc ncp_iodesc[] __initdata = {};
83 83
84static void __init ncp_map_io(void) 84static void __init ncp_map_io(void)
85{ 85{
diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c
index bc9a7dea567f..ea51dbe76e3e 100644
--- a/arch/arm/mach-s3c6410/mach-smdk6410.c
+++ b/arch/arm/mach-s3c6410/mach-smdk6410.c
@@ -65,16 +65,30 @@ static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
65 [0] = { 65 [0] = {
66 .hwport = 0, 66 .hwport = 0,
67 .flags = 0, 67 .flags = 0,
68 .ucon = 0x3c5, 68 .ucon = UCON,
69 .ulcon = 0x03, 69 .ulcon = ULCON,
70 .ufcon = 0x51, 70 .ufcon = UFCON,
71 }, 71 },
72 [1] = { 72 [1] = {
73 .hwport = 1, 73 .hwport = 1,
74 .flags = 0, 74 .flags = 0,
75 .ucon = 0x3c5, 75 .ucon = UCON,
76 .ulcon = 0x03, 76 .ulcon = ULCON,
77 .ufcon = 0x51, 77 .ufcon = UFCON,
78 },
79 [2] = {
80 .hwport = 2,
81 .flags = 0,
82 .ucon = UCON,
83 .ulcon = ULCON,
84 .ufcon = UFCON,
85 },
86 [3] = {
87 .hwport = 3,
88 .flags = 0,
89 .ucon = UCON,
90 .ulcon = ULCON,
91 .ufcon = UFCON,
78 }, 92 },
79}; 93};
80 94
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
new file mode 100644
index 000000000000..b1a4ba504416
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -0,0 +1,22 @@
1# arch/arm/mach-s5pc100/Kconfig
2#
3# Copyright 2009 Samsung Electronics Co.
4# Byungho Min <bhmin@samsung.com>
5#
6# Licensed under GPLv2
7
8# Configuration options for the S5PC100 CPU
9
10config CPU_S5PC100
11 bool
12 select CPU_S5PC100_INIT
13 select CPU_S5PC100_CLOCK
14 help
15 Enable S5PC100 CPU support
16
17config MACH_SMDKC100
18 bool "SMDKC100"
19 select CPU_S5PC100
20 select S5PC1XX_SETUP_I2C1
21 help
22 Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
new file mode 100644
index 000000000000..afc89b381d7a
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -0,0 +1,17 @@
1# arch/arm/mach-s5pc100/Makefile
2#
3# Copyright 2009 Samsung Electronics Co.
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12# Core support for S5PC100 system
13
14obj-$(CONFIG_CPU_S5PC100) += cpu.o
15
16# machine support
17obj-$(CONFIG_MACH_SMDKC100) += mach-smdkc100.o
diff --git a/arch/arm/mach-s5pc100/Makefile.boot b/arch/arm/mach-s5pc100/Makefile.boot
new file mode 100644
index 000000000000..ff90aa13bd67
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Makefile.boot
@@ -0,0 +1,2 @@
1 zreladdr-y := 0x20008000
2params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
new file mode 100644
index 000000000000..0e718890da32
--- /dev/null
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -0,0 +1,97 @@
1/* linux/arch/arm/mach-s5pc100/cpu.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Based on mach-s3c6410/cpu.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/timer.h>
18#include <linux/init.h>
19#include <linux/clk.h>
20#include <linux/io.h>
21#include <linux/sysdev.h>
22#include <linux/serial_core.h>
23#include <linux/platform_device.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/irq.h>
28
29#include <mach/hardware.h>
30#include <mach/map.h>
31#include <asm/irq.h>
32
33#include <plat/cpu-freq.h>
34#include <plat/regs-serial.h>
35
36#include <plat/cpu.h>
37#include <plat/devs.h>
38#include <plat/clock.h>
39#include <plat/sdhci.h>
40#include <plat/iic-core.h>
41#include <plat/s5pc100.h>
42
43/* Initial IO mappings */
44
45static struct map_desc s5pc100_iodesc[] __initdata = {
46};
47
48/* s5pc100_map_io
49 *
50 * register the standard cpu IO areas
51*/
52
53void __init s5pc100_map_io(void)
54{
55 iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
56
57 /* initialise device information early */
58}
59
60void __init s5pc100_init_clocks(int xtal)
61{
62 printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
63 s3c24xx_register_baseclocks(xtal);
64 s5pc1xx_register_clocks();
65 s5pc100_register_clocks();
66 s5pc100_setup_clocks();
67}
68
69void __init s5pc100_init_irq(void)
70{
71 u32 vic_valid[] = {~0, ~0, ~0};
72
73 /* VIC0, VIC1, and VIC2 are fully populated. */
74 s5pc1xx_init_irq(vic_valid, ARRAY_SIZE(vic_valid));
75}
76
77struct sysdev_class s5pc100_sysclass = {
78 .name = "s5pc100-core",
79};
80
81static struct sys_device s5pc100_sysdev = {
82 .cls = &s5pc100_sysclass,
83};
84
85static int __init s5pc100_core_init(void)
86{
87 return sysdev_class_register(&s5pc100_sysclass);
88}
89
90core_initcall(s5pc100_core_init);
91
92int __init s5pc100_init(void)
93{
94 printk(KERN_DEBUG "S5PC100: Initialising architecture\n");
95
96 return sysdev_register(&s5pc100_sysdev);
97}
diff --git a/arch/arm/mach-s5pc100/include/mach/debug-macro.S b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
new file mode 100644
index 000000000000..9d142ccf654b
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
1/* arch/arm/mach-s5pc100/include/mach/debug-macro.S
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 *
7 * Based on mach-s3c6400/include/mach/debug-macro.S
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14/* pull in the relevant register and map files. */
15
16#include <mach/map.h>
17#include <plat/regs-serial.h>
18
19 /* note, for the boot process to work we have to keep the UART
20 * virtual address aligned to an 1MiB boundary for the L1
21 * mapping the head code makes. We keep the UART virtual address
22 * aligned and add in the offset when we load the value here.
23 */
24
25 .macro addruart, rx
26 mrc p15, 0, \rx, c1, c0
27 tst \rx, #1
28 ldreq \rx, = S3C_PA_UART
29 ldrne \rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
30 add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
31 .endm
32
33/* include the reset of the code which will do the work, we're only
34 * compiling for a single cpu processor type so the default of s3c2440
35 * will be fine with us.
36 */
37
38#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5pc100/include/mach/entry-macro.S b/arch/arm/mach-s5pc100/include/mach/entry-macro.S
new file mode 100644
index 000000000000..67131939e626
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/entry-macro.S
@@ -0,0 +1,50 @@
1/* arch/arm/mach-s5pc100/include/mach/entry-macro.S
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Based on mach-s3c6400/include/mach/entry-macro.S
7 *
8 * Low-level IRQ helper macros for the Samsung S5PC1XX series
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13*/
14
15#include <asm/hardware/vic.h>
16#include <mach/map.h>
17#include <plat/irqs.h>
18
19 .macro disable_fiq
20 .endm
21
22 .macro get_irqnr_preamble, base, tmp
23 ldr \base, =S3C_VA_VIC0
24 .endm
25
26 .macro arch_ret_to_user, tmp1, tmp2
27 .endm
28
29 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
30
31 @ check the vic0
32 mov \irqnr, # S3C_IRQ_OFFSET + 31
33 ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
34 teq \irqstat, #0
35
36 @ otherwise try vic1
37 addeq \tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0)
38 addeq \irqnr, \irqnr, #32
39 ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
40 teqeq \irqstat, #0
41
42 @ otherwise try vic2
43 addeq \tmp, \base, #(S3C_VA_VIC2 - S3C_VA_VIC0)
44 addeq \irqnr, \irqnr, #32
45 ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
46 teqeq \irqstat, #0
47
48 clzne \irqstat, \irqstat
49 subne \irqnr, \irqnr, \irqstat
50 .endm
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio-core.h b/arch/arm/mach-s5pc100/include/mach/gpio-core.h
new file mode 100644
index 000000000000..ad28d8ec8a78
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/gpio-core.h
@@ -0,0 +1,21 @@
1/* arch/arm/mach-s5pc100/include/mach/gpio-core.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - GPIO core support
7 *
8 * Based on mach-s3c6400/include/mach/gpio-core.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef __ASM_ARCH_GPIO_CORE_H
16#define __ASM_ARCH_GPIO_CORE_H __FILE__
17
18/* currently we just include the platform support */
19#include <plat/gpio-core.h>
20
21#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
new file mode 100644
index 000000000000..c74fc93d7d15
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -0,0 +1,146 @@
1/* arch/arm/mach-s5pc100/include/mach/gpio.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - GPIO lib support
7 *
8 * Base on mach-s3c6400/include/mach/gpio.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#define gpio_get_value __gpio_get_value
16#define gpio_set_value __gpio_set_value
17#define gpio_cansleep __gpio_cansleep
18#define gpio_to_irq __gpio_to_irq
19
20/* GPIO bank sizes */
21#define S5PC1XX_GPIO_A0_NR (8)
22#define S5PC1XX_GPIO_A1_NR (5)
23#define S5PC1XX_GPIO_B_NR (8)
24#define S5PC1XX_GPIO_C_NR (5)
25#define S5PC1XX_GPIO_D_NR (7)
26#define S5PC1XX_GPIO_E0_NR (8)
27#define S5PC1XX_GPIO_E1_NR (6)
28#define S5PC1XX_GPIO_F0_NR (8)
29#define S5PC1XX_GPIO_F1_NR (8)
30#define S5PC1XX_GPIO_F2_NR (8)
31#define S5PC1XX_GPIO_F3_NR (4)
32#define S5PC1XX_GPIO_G0_NR (8)
33#define S5PC1XX_GPIO_G1_NR (3)
34#define S5PC1XX_GPIO_G2_NR (7)
35#define S5PC1XX_GPIO_G3_NR (7)
36#define S5PC1XX_GPIO_H0_NR (8)
37#define S5PC1XX_GPIO_H1_NR (8)
38#define S5PC1XX_GPIO_H2_NR (8)
39#define S5PC1XX_GPIO_H3_NR (8)
40#define S5PC1XX_GPIO_I_NR (8)
41#define S5PC1XX_GPIO_J0_NR (8)
42#define S5PC1XX_GPIO_J1_NR (5)
43#define S5PC1XX_GPIO_J2_NR (8)
44#define S5PC1XX_GPIO_J3_NR (8)
45#define S5PC1XX_GPIO_J4_NR (4)
46#define S5PC1XX_GPIO_K0_NR (8)
47#define S5PC1XX_GPIO_K1_NR (6)
48#define S5PC1XX_GPIO_K2_NR (8)
49#define S5PC1XX_GPIO_K3_NR (8)
50#define S5PC1XX_GPIO_MP00_NR (8)
51#define S5PC1XX_GPIO_MP01_NR (8)
52#define S5PC1XX_GPIO_MP02_NR (8)
53#define S5PC1XX_GPIO_MP03_NR (8)
54#define S5PC1XX_GPIO_MP04_NR (5)
55
56/* GPIO bank numbes */
57
58/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
59 * space for debugging purposes so that any accidental
60 * change from one gpio bank to another can be caught.
61*/
62
63#define S5PC1XX_GPIO_NEXT(__gpio) \
64 ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
65
66enum s3c_gpio_number {
67 S5PC1XX_GPIO_A0_START = 0,
68 S5PC1XX_GPIO_A1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
69 S5PC1XX_GPIO_B_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
70 S5PC1XX_GPIO_C_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
71 S5PC1XX_GPIO_D_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
72 S5PC1XX_GPIO_E0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
73 S5PC1XX_GPIO_E1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E0),
74 S5PC1XX_GPIO_F0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E1),
75 S5PC1XX_GPIO_F1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F0),
76 S5PC1XX_GPIO_F2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F1),
77 S5PC1XX_GPIO_F3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F2),
78 S5PC1XX_GPIO_G0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F3),
79 S5PC1XX_GPIO_G1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G0),
80 S5PC1XX_GPIO_G2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G1),
81 S5PC1XX_GPIO_G3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G2),
82 S5PC1XX_GPIO_H0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G3),
83 S5PC1XX_GPIO_H1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H0),
84 S5PC1XX_GPIO_H2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H1),
85 S5PC1XX_GPIO_H3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H2),
86 S5PC1XX_GPIO_I_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H3),
87 S5PC1XX_GPIO_J0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_I),
88 S5PC1XX_GPIO_J1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J0),
89 S5PC1XX_GPIO_J2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J1),
90 S5PC1XX_GPIO_J3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J2),
91 S5PC1XX_GPIO_J4_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J3),
92 S5PC1XX_GPIO_K0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J4),
93 S5PC1XX_GPIO_K1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
94 S5PC1XX_GPIO_K2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
95 S5PC1XX_GPIO_K3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
96 S5PC1XX_GPIO_MP00_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
97 S5PC1XX_GPIO_MP01_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
98 S5PC1XX_GPIO_MP02_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
99 S5PC1XX_GPIO_MP03_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
100 S5PC1XX_GPIO_MP04_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
101};
102
103/* S5PC1XX GPIO number definitions. */
104#define S5PC1XX_GPA0(_nr) (S5PC1XX_GPIO_A0_START + (_nr))
105#define S5PC1XX_GPA1(_nr) (S5PC1XX_GPIO_A1_START + (_nr))
106#define S5PC1XX_GPB(_nr) (S5PC1XX_GPIO_B_START + (_nr))
107#define S5PC1XX_GPC(_nr) (S5PC1XX_GPIO_C_START + (_nr))
108#define S5PC1XX_GPD(_nr) (S5PC1XX_GPIO_D_START + (_nr))
109#define S5PC1XX_GPE0(_nr) (S5PC1XX_GPIO_E0_START + (_nr))
110#define S5PC1XX_GPE1(_nr) (S5PC1XX_GPIO_E1_START + (_nr))
111#define S5PC1XX_GPF0(_nr) (S5PC1XX_GPIO_F0_START + (_nr))
112#define S5PC1XX_GPF1(_nr) (S5PC1XX_GPIO_F1_START + (_nr))
113#define S5PC1XX_GPF2(_nr) (S5PC1XX_GPIO_F2_START + (_nr))
114#define S5PC1XX_GPF3(_nr) (S5PC1XX_GPIO_F3_START + (_nr))
115#define S5PC1XX_GPG0(_nr) (S5PC1XX_GPIO_G0_START + (_nr))
116#define S5PC1XX_GPG1(_nr) (S5PC1XX_GPIO_G1_START + (_nr))
117#define S5PC1XX_GPG2(_nr) (S5PC1XX_GPIO_G2_START + (_nr))
118#define S5PC1XX_GPG3(_nr) (S5PC1XX_GPIO_G3_START + (_nr))
119#define S5PC1XX_GPH0(_nr) (S5PC1XX_GPIO_H0_START + (_nr))
120#define S5PC1XX_GPH1(_nr) (S5PC1XX_GPIO_H1_START + (_nr))
121#define S5PC1XX_GPH2(_nr) (S5PC1XX_GPIO_H2_START + (_nr))
122#define S5PC1XX_GPH3(_nr) (S5PC1XX_GPIO_H3_START + (_nr))
123#define S5PC1XX_GPI(_nr) (S5PC1XX_GPIO_I_START + (_nr))
124#define S5PC1XX_GPJ0(_nr) (S5PC1XX_GPIO_J0_START + (_nr))
125#define S5PC1XX_GPJ1(_nr) (S5PC1XX_GPIO_J1_START + (_nr))
126#define S5PC1XX_GPJ2(_nr) (S5PC1XX_GPIO_J2_START + (_nr))
127#define S5PC1XX_GPJ3(_nr) (S5PC1XX_GPIO_J3_START + (_nr))
128#define S5PC1XX_GPJ4(_nr) (S5PC1XX_GPIO_J4_START + (_nr))
129#define S5PC1XX_GPK0(_nr) (S5PC1XX_GPIO_K0_START + (_nr))
130#define S5PC1XX_GPK1(_nr) (S5PC1XX_GPIO_K1_START + (_nr))
131#define S5PC1XX_GPK2(_nr) (S5PC1XX_GPIO_K2_START + (_nr))
132#define S5PC1XX_GPK3(_nr) (S5PC1XX_GPIO_K3_START + (_nr))
133#define S5PC1XX_MP00(_nr) (S5PC1XX_GPIO_MP00_START + (_nr))
134#define S5PC1XX_MP01(_nr) (S5PC1XX_GPIO_MP01_START + (_nr))
135#define S5PC1XX_MP02(_nr) (S5PC1XX_GPIO_MP02_START + (_nr))
136#define S5PC1XX_MP03(_nr) (S5PC1XX_GPIO_MP03_START + (_nr))
137#define S5PC1XX_MP04(_nr) (S5PC1XX_GPIO_MP04_START + (_nr))
138
139/* the end of the S5PC1XX specific gpios */
140#define S5PC1XX_GPIO_END (S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
141#define S3C_GPIO_END S5PC1XX_GPIO_END
142
143/* define the number of gpios we need to the one after the MP04() range */
144#define ARCH_NR_GPIOS (S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
145
146#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s5pc100/include/mach/hardware.h b/arch/arm/mach-s5pc100/include/mach/hardware.h
new file mode 100644
index 000000000000..6b38618c2fd9
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/hardware.h
@@ -0,0 +1,14 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/hardware.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - Hardware support
7 */
8
9#ifndef __ASM_ARCH_HARDWARE_H
10#define __ASM_ARCH_HARDWARE_H __FILE__
11
12/* currently nothing here, placeholder */
13
14#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
new file mode 100644
index 000000000000..622720dba289
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -0,0 +1,14 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/irqs.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - IRQ definitions
7 */
8
9#ifndef __ASM_ARCH_IRQS_H
10#define __ASM_ARCH_IRQS_H __FILE__
11
12#include <plat/irqs.h>
13
14#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
new file mode 100644
index 000000000000..9e9f39130b2c
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -0,0 +1,75 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/map.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Based on mach-s3c6400/include/mach/map.h
7 *
8 * S5PC1XX - Memory map definitions
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef __ASM_ARCH_MAP_H
16#define __ASM_ARCH_MAP_H __FILE__
17
18#include <plat/map-base.h>
19
20
21/* Chip ID */
22#define S5PC100_PA_CHIPID (0xE0000000)
23#define S5PC1XX_PA_CHIPID S5PC100_PA_CHIPID
24#define S5PC1XX_VA_CHIPID S3C_VA_SYS
25
26/* System */
27#define S5PC100_PA_SYS (0xE0100000)
28#define S5PC100_PA_CLK (S5PC100_PA_SYS + 0x0)
29#define S5PC100_PA_PWR (S5PC100_PA_SYS + 0x8000)
30#define S5PC1XX_PA_CLK S5PC100_PA_CLK
31#define S5PC1XX_PA_PWR S5PC100_PA_PWR
32#define S5PC1XX_VA_CLK (S3C_VA_SYS + 0x10000)
33#define S5PC1XX_VA_PWR (S3C_VA_SYS + 0x20000)
34
35/* Interrupt */
36#define S5PC100_PA_VIC (0xE4000000)
37#define S5PC100_VA_VIC S3C_VA_IRQ
38#define S5PC100_PA_VIC_OFFSET 0x100000
39#define S5PC100_VA_VIC_OFFSET 0x10000
40#define S5PC1XX_PA_VIC(x) (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
41#define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
42
43/* Timer */
44#define S5PC100_PA_TIMER (0xEA000000)
45#define S5PC1XX_PA_TIMER S5PC100_PA_TIMER
46#define S5PC1XX_VA_TIMER S3C_VA_TIMER
47
48/* UART */
49#define S5PC100_PA_UART (0xEC000000)
50#define S5PC1XX_PA_UART S5PC100_PA_UART
51#define S5PC1XX_VA_UART S3C_VA_UART
52
53/* IIC */
54#define S5PC100_PA_IIC (0xEC100000)
55
56/* ETC */
57#define S5PC100_PA_SDRAM (0x20000000)
58
59/* compatibility defines. */
60#define S3C_PA_UART S5PC100_PA_UART
61#define S3C_PA_UART0 (S5PC100_PA_UART + 0x0)
62#define S3C_PA_UART1 (S5PC100_PA_UART + 0x400)
63#define S3C_PA_UART2 (S5PC100_PA_UART + 0x800)
64#define S3C_PA_UART3 (S5PC100_PA_UART + 0xC00)
65#define S3C_VA_UART0 (S3C_VA_UART + 0x0)
66#define S3C_VA_UART1 (S3C_VA_UART + 0x400)
67#define S3C_VA_UART2 (S3C_VA_UART + 0x800)
68#define S3C_VA_UART3 (S3C_VA_UART + 0xC00)
69#define S3C_UART_OFFSET 0x400
70#define S3C_VA_VIC0 (S3C_VA_IRQ + 0x0)
71#define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000)
72#define S3C_VA_VIC2 (S3C_VA_IRQ + 0x20000)
73#define S3C_PA_IIC S5PC100_PA_IIC
74
75#endif /* __ASM_ARCH_C100_MAP_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h
new file mode 100644
index 000000000000..4b60d18179f7
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/memory.h
@@ -0,0 +1,18 @@
1/* arch/arm/mach-s5pc100/include/mach/memory.h
2 *
3 * Copyright 2008 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Based on mach-s3c6400/include/mach/memory.h
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_MEMORY_H
14#define __ASM_ARCH_MEMORY_H
15
16#define PHYS_OFFSET UL(0x20000000)
17
18#endif
diff --git a/arch/arm/mach-s5pc100/include/mach/pwm-clock.h b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
new file mode 100644
index 000000000000..b34d2f7aae52
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
@@ -0,0 +1,56 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - pwm clock and timer support
7 *
8 * Based on mach-s3c6400/include/mach/pwm-clock.h
9 */
10
11/**
12 * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
13 * @tcfg: The timer TCFG1 register bits shifted down to 0.
14 *
15 * Return true if the given configuration from TCFG1 is a TCLK instead
16 * any of the TDIV clocks.
17 */
18static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
19{
20 return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
21}
22
23/**
24 * tcfg_to_divisor() - convert tcfg1 setting to a divisor
25 * @tcfg1: The tcfg1 setting, shifted down.
26 *
27 * Get the divisor value for the given tcfg1 setting. We assume the
28 * caller has already checked to see if this is not a TCLK source.
29 */
30static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
31{
32 return 1 << tcfg1;
33}
34
35/**
36 * pwm_tdiv_has_div1() - does the tdiv setting have a /1
37 *
38 * Return true if we have a /1 in the tdiv setting.
39 */
40static inline unsigned int pwm_tdiv_has_div1(void)
41{
42 return 1;
43}
44
45/**
46 * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
47 * @div: The divisor to calculate the bit information for.
48 *
49 * Turn a divisor into the necessary bit field for TCFG1.
50 */
51static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
52{
53 return ilog2(div);
54}
55
56#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-irq.h b/arch/arm/mach-s5pc100/include/mach/regs-irq.h
new file mode 100644
index 000000000000..751ac15438c8
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-irq.h
@@ -0,0 +1,24 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/regs-irq.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX - IRQ register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_IRQ_H
14#define __ASM_ARCH_REGS_IRQ_H __FILE__
15
16#include <mach/map.h>
17#include <asm/hardware/vic.h>
18
19/* interrupt controller */
20#define S5PC1XX_VIC0REG(x) ((x) + S5PC1XX_VA_VIC(0))
21#define S5PC1XX_VIC1REG(x) ((x) + S5PC1XX_VA_VIC(1))
22#define S5PC1XX_VIC2REG(x) ((x) + S5PC1XX_VA_VIC(2))
23
24#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
new file mode 100644
index 000000000000..e39014375470
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/system.h
@@ -0,0 +1,24 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/system.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX - system implementation
7 *
8 * Based on mach-s3c6400/include/mach/system.h
9 */
10
11#ifndef __ASM_ARCH_SYSTEM_H
12#define __ASM_ARCH_SYSTEM_H __FILE__
13
14static void arch_idle(void)
15{
16 /* nothing here yet */
17}
18
19static void arch_reset(char mode, const char *cmd)
20{
21 /* nothing here yet */
22}
23
24#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h
new file mode 100644
index 000000000000..d3de0f3591ae
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/tick.h
@@ -0,0 +1,29 @@
1/* linux/arch/arm/mach-s5pc100/include/mach/tick.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S3C64XX - Timer tick support definitions
7 *
8 * Based on mach-s3c6400/include/mach/tick.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef __ASM_ARCH_TICK_H
16#define __ASM_ARCH_TICK_H __FILE__
17
18/* note, the timer interrutps turn up in 2 places, the vic and then
19 * the timer block. We take the VIC as the base at the moment.
20 */
21static inline u32 s3c24xx_ostimer_pending(void)
22{
23 u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
24 return pend & 1 << (IRQ_TIMER4 - S5PC1XX_IRQ_VIC0(0));
25}
26
27#define TICK_MAX (0xffffffff)
28
29#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/uncompress.h b/arch/arm/mach-s5pc100/include/mach/uncompress.h
new file mode 100644
index 000000000000..01ccf535e76c
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/uncompress.h
@@ -0,0 +1,28 @@
1/* arch/arm/mach-s5pc100/include/mach/uncompress.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - uncompress code
7 *
8 * Based on mach-s3c6400/include/mach/uncompress.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#ifndef __ASM_ARCH_UNCOMPRESS_H
16#define __ASM_ARCH_UNCOMPRESS_H
17
18#include <mach/map.h>
19#include <plat/uncompress.h>
20
21static void arch_detect_cpu(void)
22{
23 /* we do not need to do any cpu detection here at the moment. */
24 fifo_mask = S3C2440_UFSTAT_TXMASK;
25 fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
26}
27
28#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
new file mode 100644
index 000000000000..214093cd7632
--- /dev/null
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -0,0 +1,103 @@
1/* linux/arch/arm/mach-s5pc100/mach-smdkc100.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Author: Byungho Min <bhmin@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10*/
11
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/interrupt.h>
15#include <linux/list.h>
16#include <linux/timer.h>
17#include <linux/init.h>
18#include <linux/serial_core.h>
19#include <linux/platform_device.h>
20#include <linux/io.h>
21#include <linux/gpio.h>
22#include <linux/i2c.h>
23#include <linux/fb.h>
24#include <linux/delay.h>
25
26#include <asm/mach/arch.h>
27#include <asm/mach/map.h>
28
29#include <mach/map.h>
30
31#include <asm/irq.h>
32#include <asm/mach-types.h>
33
34#include <plat/regs-serial.h>
35
36#include <plat/clock.h>
37#include <plat/devs.h>
38#include <plat/cpu.h>
39#include <plat/s5pc100.h>
40
41#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
42#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
43#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
44
45static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
46 [0] = {
47 .hwport = 0,
48 .flags = 0,
49 .ucon = 0x3c5,
50 .ulcon = 0x03,
51 .ufcon = 0x51,
52 },
53 [1] = {
54 .hwport = 1,
55 .flags = 0,
56 .ucon = 0x3c5,
57 .ulcon = 0x03,
58 .ufcon = 0x51,
59 },
60 [2] = {
61 .hwport = 2,
62 .flags = 0,
63 .ucon = 0x3c5,
64 .ulcon = 0x03,
65 .ufcon = 0x51,
66 },
67 [3] = {
68 .hwport = 3,
69 .flags = 0,
70 .ucon = 0x3c5,
71 .ulcon = 0x03,
72 .ufcon = 0x51,
73 },
74};
75
76static struct map_desc smdkc100_iodesc[] = {};
77
78static struct platform_device *smdkc100_devices[] __initdata = {
79};
80
81static void __init smdkc100_map_io(void)
82{
83 s5pc1xx_init_io(smdkc100_iodesc, ARRAY_SIZE(smdkc100_iodesc));
84 s3c24xx_init_clocks(12000000);
85 s3c24xx_init_uarts(smdkc100_uartcfgs, ARRAY_SIZE(smdkc100_uartcfgs));
86}
87
88static void __init smdkc100_machine_init(void)
89{
90 platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
91}
92
93MACHINE_START(SMDKC100, "SMDKC100")
94 /* Maintainer: Byungho Min <bhmin@samsung.com> */
95 .phys_io = S5PC1XX_PA_UART & 0xfff00000,
96 .io_pg_offst = (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
97 .boot_params = S5PC100_PA_SDRAM + 0x100,
98
99 .init_irq = s5pc100_init_irq,
100 .map_io = smdkc100_map_io,
101 .init_machine = smdkc100_machine_init,
102 .timer = &s3c24xx_timer,
103MACHINE_END
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
index 3138d3955c9e..585cc013639d 100644
--- a/arch/arm/mach-u300/mmc.c
+++ b/arch/arm/mach-u300/mmc.c
@@ -156,6 +156,8 @@ int __devinit mmc_init(struct amba_device *adev)
156 mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29; 156 mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29;
157 mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd; 157 mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd;
158 mmci_card->mmc0_plat_data.status = mmc_status; 158 mmci_card->mmc0_plat_data.status = mmc_status;
159 mmci_card->mmc0_plat_data.gpio_wp = -1;
160 mmci_card->mmc0_plat_data.gpio_cd = -1;
159 161
160 mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; 162 mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data;
161 163
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 31093af7d052..975eae41ee66 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -26,6 +26,7 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/amba/bus.h> 27#include <linux/amba/bus.h>
28#include <linux/amba/clcd.h> 28#include <linux/amba/clcd.h>
29#include <linux/amba/pl061.h>
29#include <linux/clocksource.h> 30#include <linux/clocksource.h>
30#include <linux/clockchips.h> 31#include <linux/clockchips.h>
31#include <linux/cnt32_to_63.h> 32#include <linux/cnt32_to_63.h>
@@ -371,6 +372,8 @@ unsigned int mmc_status(struct device *dev)
371static struct mmc_platform_data mmc0_plat_data = { 372static struct mmc_platform_data mmc0_plat_data = {
372 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 373 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
373 .status = mmc_status, 374 .status = mmc_status,
375 .gpio_wp = -1,
376 .gpio_cd = -1,
374}; 377};
375 378
376/* 379/*
@@ -705,6 +708,16 @@ static struct clcd_board clcd_plat_data = {
705 .remove = versatile_clcd_remove, 708 .remove = versatile_clcd_remove,
706}; 709};
707 710
711static struct pl061_platform_data gpio0_plat_data = {
712 .gpio_base = 0,
713 .irq_base = IRQ_GPIO0_START,
714};
715
716static struct pl061_platform_data gpio1_plat_data = {
717 .gpio_base = 8,
718 .irq_base = IRQ_GPIO1_START,
719};
720
708#define AACI_IRQ { IRQ_AACI, NO_IRQ } 721#define AACI_IRQ { IRQ_AACI, NO_IRQ }
709#define AACI_DMA { 0x80, 0x81 } 722#define AACI_DMA { 0x80, 0x81 }
710#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } 723#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
@@ -767,8 +780,8 @@ AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
767AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); 780AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
768AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); 781AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
769AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); 782AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
770AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL); 783AMBA_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data);
771AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); 784AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
772AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); 785AMBA_DEVICE(rtc, "dev:e8", RTC, NULL);
773AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); 786AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
774AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); 787AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
diff --git a/arch/arm/mach-versatile/include/mach/gpio.h b/arch/arm/mach-versatile/include/mach/gpio.h
new file mode 100644
index 000000000000..94ff27678a46
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/gpio.h
@@ -0,0 +1,6 @@
1#include <asm-generic/gpio.h>
2
3#define gpio_get_value __gpio_get_value
4#define gpio_set_value __gpio_set_value
5#define gpio_cansleep __gpio_cansleep
6#define gpio_to_irq __gpio_to_irq
diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h
index 9bfdb30e1f3f..bf44c61bd1f6 100644
--- a/arch/arm/mach-versatile/include/mach/irqs.h
+++ b/arch/arm/mach-versatile/include/mach/irqs.h
@@ -122,4 +122,13 @@
122#define IRQ_SIC_PCI3 (IRQ_SIC_START + SIC_INT_PCI3) 122#define IRQ_SIC_PCI3 (IRQ_SIC_START + SIC_INT_PCI3)
123#define IRQ_SIC_END 63 123#define IRQ_SIC_END 63
124 124
125#define NR_IRQS 64 125#define IRQ_GPIO0_START (IRQ_SIC_END + 1)
126#define IRQ_GPIO0_END (IRQ_GPIO0_START + 31)
127#define IRQ_GPIO1_START (IRQ_GPIO0_END + 1)
128#define IRQ_GPIO1_END (IRQ_GPIO1_START + 31)
129#define IRQ_GPIO2_START (IRQ_GPIO1_END + 1)
130#define IRQ_GPIO2_END (IRQ_GPIO2_START + 31)
131#define IRQ_GPIO3_START (IRQ_GPIO2_END + 1)
132#define IRQ_GPIO3_END (IRQ_GPIO3_START + 31)
133
134#define NR_IRQS (IRQ_GPIO3_END + 1)
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index aa051c0884f8..9af8d8154df5 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -23,6 +23,7 @@
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/sysdev.h> 24#include <linux/sysdev.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl061.h>
26#include <linux/io.h> 27#include <linux/io.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -43,6 +44,18 @@
43static struct mmc_platform_data mmc1_plat_data = { 44static struct mmc_platform_data mmc1_plat_data = {
44 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 45 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
45 .status = mmc_status, 46 .status = mmc_status,
47 .gpio_wp = -1,
48 .gpio_cd = -1,
49};
50
51static struct pl061_platform_data gpio2_plat_data = {
52 .gpio_base = 16,
53 .irq_base = IRQ_GPIO2_START,
54};
55
56static struct pl061_platform_data gpio3_plat_data = {
57 .gpio_base = 24,
58 .irq_base = IRQ_GPIO3_START,
46}; 59};
47 60
48#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } 61#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
@@ -70,8 +83,8 @@ AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL);
70AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); 83AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data);
71 84
72/* DevChip Primecells */ 85/* DevChip Primecells */
73AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); 86AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
74AMBA_DEVICE(gpio3, "dev:e7", GPIO3, NULL); 87AMBA_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data);
75 88
76static struct amba_device *amba_devs[] __initdata = { 89static struct amba_device *amba_devs[] __initdata = {
77 &uart3_device, 90 &uart3_device,
diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig
index 8e4178fe5ec2..69bab32a8bc2 100644
--- a/arch/arm/mach-w90x900/Kconfig
+++ b/arch/arm/mach-w90x900/Kconfig
@@ -5,6 +5,16 @@ config CPU_W90P910
5 help 5 help
6 Support for W90P910 of Nuvoton W90X900 CPUs. 6 Support for W90P910 of Nuvoton W90X900 CPUs.
7 7
8config CPU_NUC950
9 bool
10 help
11 Support for NUCP950 of Nuvoton NUC900 CPUs.
12
13config CPU_NUC960
14 bool
15 help
16 Support for NUCP960 of Nuvoton NUC900 CPUs.
17
8menu "W90P910 Machines" 18menu "W90P910 Machines"
9 19
10config MACH_W90P910EVB 20config MACH_W90P910EVB
@@ -16,4 +26,24 @@ config MACH_W90P910EVB
16 26
17endmenu 27endmenu
18 28
29menu "NUC950 Machines"
30
31config MACH_W90P950EVB
32 bool "Nuvoton NUC950 Evaluation Board"
33 select CPU_NUC950
34 help
35 Say Y here if you are using the Nuvoton NUC950EVB
36
37endmenu
38
39menu "NUC960 Machines"
40
41config MACH_W90N960EVB
42 bool "Nuvoton NUC960 Evaluation Board"
43 select CPU_NUC960
44 help
45 Say Y here if you are using the Nuvoton NUC960EVB
46
47endmenu
48
19endif 49endif
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
index d50c94f4dbdf..828c0326441e 100644
--- a/arch/arm/mach-w90x900/Makefile
+++ b/arch/arm/mach-w90x900/Makefile
@@ -4,12 +4,16 @@
4 4
5# Object file lists. 5# Object file lists.
6 6
7obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o 7obj-y := irq.o time.o mfp.o gpio.o clock.o
8 8obj-y += clksel.o dev.o cpu.o
9# W90X900 CPU support files 9# W90X900 CPU support files
10 10
11obj-$(CONFIG_CPU_W90P910) += w90p910.o 11obj-$(CONFIG_CPU_W90P910) += nuc910.o
12obj-$(CONFIG_CPU_NUC950) += nuc950.o
13obj-$(CONFIG_CPU_NUC960) += nuc960.o
12 14
13# machine support 15# machine support
14 16
15obj-$(CONFIG_MACH_W90P910EVB) += mach-w90p910evb.o 17obj-$(CONFIG_MACH_W90P910EVB) += mach-nuc910evb.o
18obj-$(CONFIG_MACH_W90P950EVB) += mach-nuc950evb.o
19obj-$(CONFIG_MACH_W90N960EVB) += mach-nuc960evb.o
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c
new file mode 100644
index 000000000000..3de4a5211c3b
--- /dev/null
+++ b/arch/arm/mach-w90x900/clksel.c
@@ -0,0 +1,91 @@
1/*
2 * linux/arch/arm/mach-w90x900/clksel.c
3 *
4 * Copyright (c) 2008 Nuvoton technology corporation
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation;version 2 of the License.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/string.h>
20#include <linux/clk.h>
21#include <linux/mutex.h>
22#include <linux/io.h>
23
24#include <mach/hardware.h>
25#include <mach/regs-clock.h>
26
27#define PLL0 0x00
28#define PLL1 0x01
29#define OTHER 0x02
30#define EXT 0x03
31#define MSOFFSET 0x0C
32#define ATAOFFSET 0x0a
33#define LCDOFFSET 0x06
34#define AUDOFFSET 0x04
35#define CPUOFFSET 0x00
36
37static DEFINE_MUTEX(clksel_sem);
38
39static void clock_source_select(const char *dev_id, unsigned int clkval)
40{
41 unsigned int clksel, offset;
42
43 clksel = __raw_readl(REG_CLKSEL);
44
45 if (strcmp(dev_id, "nuc900-ms") == 0)
46 offset = MSOFFSET;
47 else if (strcmp(dev_id, "nuc900-atapi") == 0)
48 offset = ATAOFFSET;
49 else if (strcmp(dev_id, "nuc900-lcd") == 0)
50 offset = LCDOFFSET;
51 else if (strcmp(dev_id, "nuc900-audio") == 0)
52 offset = AUDOFFSET;
53 else
54 offset = CPUOFFSET;
55
56 clksel &= ~(0x03 << offset);
57 clksel |= (clkval << offset);
58
59 __raw_writel(clksel, REG_CLKSEL);
60}
61
62void nuc900_clock_source(struct device *dev, unsigned char *src)
63{
64 unsigned int clkval;
65 const char *dev_id;
66
67 BUG_ON(!src);
68 clkval = 0;
69
70 mutex_lock(&clksel_sem);
71
72 if (dev)
73 dev_id = dev_name(dev);
74 else
75 dev_id = "cpufreq";
76
77 if (strcmp(src, "pll0") == 0)
78 clkval = PLL0;
79 else if (strcmp(src, "pll1") == 0)
80 clkval = PLL1;
81 else if (strcmp(src, "ext") == 0)
82 clkval = EXT;
83 else if (strcmp(src, "oth") == 0)
84 clkval = OTHER;
85
86 clock_source_select(dev_id, clkval);
87
88 mutex_unlock(&clksel_sem);
89}
90EXPORT_SYMBOL(nuc900_clock_source);
91
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c
index f420613cd395..b785994bab0a 100644
--- a/arch/arm/mach-w90x900/clock.c
+++ b/arch/arm/mach-w90x900/clock.c
@@ -25,6 +25,8 @@
25 25
26#include "clock.h" 26#include "clock.h"
27 27
28#define SUBCLK 0x24
29
28static DEFINE_SPINLOCK(clocks_lock); 30static DEFINE_SPINLOCK(clocks_lock);
29 31
30int clk_enable(struct clk *clk) 32int clk_enable(struct clk *clk)
@@ -53,7 +55,13 @@ void clk_disable(struct clk *clk)
53} 55}
54EXPORT_SYMBOL(clk_disable); 56EXPORT_SYMBOL(clk_disable);
55 57
56void w90x900_clk_enable(struct clk *clk, int enable) 58unsigned long clk_get_rate(struct clk *clk)
59{
60 return 15000000;
61}
62EXPORT_SYMBOL(clk_get_rate);
63
64void nuc900_clk_enable(struct clk *clk, int enable)
57{ 65{
58 unsigned int clocks = clk->cken; 66 unsigned int clocks = clk->cken;
59 unsigned long clken; 67 unsigned long clken;
@@ -68,6 +76,22 @@ void w90x900_clk_enable(struct clk *clk, int enable)
68 __raw_writel(clken, W90X900_VA_CLKPWR); 76 __raw_writel(clken, W90X900_VA_CLKPWR);
69} 77}
70 78
79void nuc900_subclk_enable(struct clk *clk, int enable)
80{
81 unsigned int clocks = clk->cken;
82 unsigned long clken;
83
84 clken = __raw_readl(W90X900_VA_CLKPWR + SUBCLK);
85
86 if (enable)
87 clken |= clocks;
88 else
89 clken &= ~clocks;
90
91 __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
92}
93
94
71void clks_register(struct clk_lookup *clks, size_t num) 95void clks_register(struct clk_lookup *clks, size_t num)
72{ 96{
73 int i; 97 int i;
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
index 4f27bda76d56..f5816a06eed6 100644
--- a/arch/arm/mach-w90x900/clock.h
+++ b/arch/arm/mach-w90x900/clock.h
@@ -12,7 +12,8 @@
12 12
13#include <asm/clkdev.h> 13#include <asm/clkdev.h>
14 14
15void w90x900_clk_enable(struct clk *clk, int enable); 15void nuc900_clk_enable(struct clk *clk, int enable);
16void nuc900_subclk_enable(struct clk *clk, int enable);
16void clks_register(struct clk_lookup *clks, size_t num); 17void clks_register(struct clk_lookup *clks, size_t num);
17 18
18struct clk { 19struct clk {
@@ -23,10 +24,17 @@ struct clk {
23 24
24#define DEFINE_CLK(_name, _ctrlbit) \ 25#define DEFINE_CLK(_name, _ctrlbit) \
25struct clk clk_##_name = { \ 26struct clk clk_##_name = { \
26 .enable = w90x900_clk_enable, \ 27 .enable = nuc900_clk_enable, \
27 .cken = (1 << _ctrlbit), \ 28 .cken = (1 << _ctrlbit), \
28 } 29 }
29 30
31#define DEFINE_SUBCLK(_name, _ctrlbit) \
32struct clk clk_##_name = { \
33 .enable = nuc900_subclk_enable, \
34 .cken = (1 << _ctrlbit), \
35 }
36
37
30#define DEF_CLKLOOK(_clk, _devname, _conname) \ 38#define DEF_CLKLOOK(_clk, _devname, _conname) \
31 { \ 39 { \
32 .clk = _clk, \ 40 .clk = _clk, \
diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c
new file mode 100644
index 000000000000..921cef991bf0
--- /dev/null
+++ b/arch/arm/mach-w90x900/cpu.c
@@ -0,0 +1,212 @@
1/*
2 * linux/arch/arm/mach-w90x900/cpu.c
3 *
4 * Copyright (c) 2009 Nuvoton corporation.
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * NUC900 series cpu common support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation;version 2 of the License.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/interrupt.h>
19#include <linux/list.h>
20#include <linux/timer.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/io.h>
24#include <linux/serial_8250.h>
25#include <linux/delay.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29#include <asm/mach/irq.h>
30#include <asm/irq.h>
31
32#include <mach/hardware.h>
33#include <mach/regs-serial.h>
34#include <mach/regs-clock.h>
35#include <mach/regs-ebi.h>
36
37#include "cpu.h"
38#include "clock.h"
39
40/* Initial IO mappings */
41
42static struct map_desc nuc900_iodesc[] __initdata = {
43 IODESC_ENT(IRQ),
44 IODESC_ENT(GCR),
45 IODESC_ENT(UART),
46 IODESC_ENT(TIMER),
47 IODESC_ENT(EBI),
48};
49
50/* Initial clock declarations. */
51static DEFINE_CLK(lcd, 0);
52static DEFINE_CLK(audio, 1);
53static DEFINE_CLK(fmi, 4);
54static DEFINE_SUBCLK(ms, 0);
55static DEFINE_SUBCLK(sd, 1);
56static DEFINE_CLK(dmac, 5);
57static DEFINE_CLK(atapi, 6);
58static DEFINE_CLK(emc, 7);
59static DEFINE_SUBCLK(rmii, 2);
60static DEFINE_CLK(usbd, 8);
61static DEFINE_CLK(usbh, 9);
62static DEFINE_CLK(g2d, 10);;
63static DEFINE_CLK(pwm, 18);
64static DEFINE_CLK(ps2, 24);
65static DEFINE_CLK(kpi, 25);
66static DEFINE_CLK(wdt, 26);
67static DEFINE_CLK(gdma, 27);
68static DEFINE_CLK(adc, 28);
69static DEFINE_CLK(usi, 29);
70static DEFINE_CLK(ext, 0);
71
72static struct clk_lookup nuc900_clkregs[] = {
73 DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
74 DEF_CLKLOOK(&clk_audio, "nuc900-audio", NULL),
75 DEF_CLKLOOK(&clk_fmi, "nuc900-fmi", NULL),
76 DEF_CLKLOOK(&clk_ms, "nuc900-fmi", "MS"),
77 DEF_CLKLOOK(&clk_sd, "nuc900-fmi", "SD"),
78 DEF_CLKLOOK(&clk_dmac, "nuc900-dmac", NULL),
79 DEF_CLKLOOK(&clk_atapi, "nuc900-atapi", NULL),
80 DEF_CLKLOOK(&clk_emc, "nuc900-emc", NULL),
81 DEF_CLKLOOK(&clk_rmii, "nuc900-emc", "RMII"),
82 DEF_CLKLOOK(&clk_usbd, "nuc900-usbd", NULL),
83 DEF_CLKLOOK(&clk_usbh, "nuc900-usbh", NULL),
84 DEF_CLKLOOK(&clk_g2d, "nuc900-g2d", NULL),
85 DEF_CLKLOOK(&clk_pwm, "nuc900-pwm", NULL),
86 DEF_CLKLOOK(&clk_ps2, "nuc900-ps2", NULL),
87 DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL),
88 DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL),
89 DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL),
90 DEF_CLKLOOK(&clk_adc, "nuc900-adc", NULL),
91 DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
92 DEF_CLKLOOK(&clk_ext, NULL, "ext"),
93};
94
95/* Initial serial platform data */
96
97struct plat_serial8250_port nuc900_uart_data[] = {
98 NUC900_8250PORT(UART0),
99};
100
101struct platform_device nuc900_serial_device = {
102 .name = "serial8250",
103 .id = PLAT8250_DEV_PLATFORM,
104 .dev = {
105 .platform_data = nuc900_uart_data,
106 },
107};
108
109/*Set NUC900 series cpu frequence*/
110static int __init nuc900_set_clkval(unsigned int cpufreq)
111{
112 unsigned int pllclk, ahbclk, apbclk, val;
113
114 pllclk = 0;
115 ahbclk = 0;
116 apbclk = 0;
117
118 switch (cpufreq) {
119 case 66:
120 pllclk = PLL_66MHZ;
121 ahbclk = AHB_CPUCLK_1_1;
122 apbclk = APB_AHB_1_2;
123 break;
124
125 case 100:
126 pllclk = PLL_100MHZ;
127 ahbclk = AHB_CPUCLK_1_1;
128 apbclk = APB_AHB_1_2;
129 break;
130
131 case 120:
132 pllclk = PLL_120MHZ;
133 ahbclk = AHB_CPUCLK_1_2;
134 apbclk = APB_AHB_1_2;
135 break;
136
137 case 166:
138 pllclk = PLL_166MHZ;
139 ahbclk = AHB_CPUCLK_1_2;
140 apbclk = APB_AHB_1_2;
141 break;
142
143 case 200:
144 pllclk = PLL_200MHZ;
145 ahbclk = AHB_CPUCLK_1_2;
146 apbclk = APB_AHB_1_2;
147 break;
148 }
149
150 __raw_writel(pllclk, REG_PLLCON0);
151
152 val = __raw_readl(REG_CLKDIV);
153 val &= ~(0x03 << 24 | 0x03 << 26);
154 val |= (ahbclk << 24 | apbclk << 26);
155 __raw_writel(val, REG_CLKDIV);
156
157 return 0;
158}
159static int __init nuc900_set_cpufreq(char *str)
160{
161 unsigned long cpufreq, val;
162
163 if (!*str)
164 return 0;
165
166 strict_strtoul(str, 0, &cpufreq);
167
168 nuc900_clock_source(NULL, "ext");
169
170 nuc900_set_clkval(cpufreq);
171
172 mdelay(1);
173
174 val = __raw_readl(REG_CKSKEW);
175 val &= ~0xff;
176 val |= DEFAULTSKEW;
177 __raw_writel(val, REG_CKSKEW);
178
179 nuc900_clock_source(NULL, "pll0");
180
181 return 1;
182}
183
184__setup("cpufreq=", nuc900_set_cpufreq);
185
186/*Init NUC900 evb io*/
187
188void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size)
189{
190 unsigned long idcode = 0x0;
191
192 iotable_init(mach_desc, mach_size);
193 iotable_init(nuc900_iodesc, ARRAY_SIZE(nuc900_iodesc));
194
195 idcode = __raw_readl(NUC900PDID);
196 if (idcode == NUC910_CPUID)
197 printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
198 else if (idcode == NUC920_CPUID)
199 printk(KERN_INFO "CPU type 0x%08lx is NUC920\n", idcode);
200 else if (idcode == NUC950_CPUID)
201 printk(KERN_INFO "CPU type 0x%08lx is NUC950\n", idcode);
202 else if (idcode == NUC960_CPUID)
203 printk(KERN_INFO "CPU type 0x%08lx is NUC960\n", idcode);
204}
205
206/*Init NUC900 clock*/
207
208void __init nuc900_init_clocks(void)
209{
210 clks_register(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
211}
212
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
index 57b5dbabeb41..4d58ba164e25 100644
--- a/arch/arm/mach-w90x900/cpu.h
+++ b/arch/arm/mach-w90x900/cpu.h
@@ -6,7 +6,7 @@
6 * Copyright (c) 2008 Nuvoton technology corporation 6 * Copyright (c) 2008 Nuvoton technology corporation
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Header file for W90X900 CPU support 9 * Header file for NUC900 CPU support
10 * 10 *
11 * Wan ZongShun <mcuos.com@gmail.com> 11 * Wan ZongShun <mcuos.com@gmail.com>
12 * 12 *
@@ -24,29 +24,7 @@
24 .type = MT_DEVICE, \ 24 .type = MT_DEVICE, \
25} 25}
26 26
27/*Cpu identifier register*/ 27#define NUC900_8250PORT(name) \
28
29#define W90X900PDID W90X900_VA_GCR
30#define W90P910_CPUID 0x02900910
31#define W90P920_CPUID 0x02900920
32#define W90P950_CPUID 0x02900950
33#define W90N960_CPUID 0x02900960
34
35struct w90x900_uartcfg;
36struct map_desc;
37struct sys_timer;
38
39/* core initialisation functions */
40
41extern void w90x900_init_irq(void);
42extern void w90p910_init_io(struct map_desc *mach_desc, int size);
43extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no);
44extern void w90p910_init_clocks(void);
45extern void w90p910_map_io(struct map_desc *mach_desc, int size);
46extern struct platform_device w90p910_serial_device;
47extern struct sys_timer w90x900_timer;
48
49#define W90X900_8250PORT(name) \
50{ \ 28{ \
51 .membase = name##_BA, \ 29 .membase = name##_BA, \
52 .mapbase = name##_PA, \ 30 .mapbase = name##_PA, \
@@ -56,3 +34,26 @@ extern struct sys_timer w90x900_timer;
56 .iotype = UPIO_MEM, \ 34 .iotype = UPIO_MEM, \
57 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ 35 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
58} 36}
37
38/*Cpu identifier register*/
39
40#define NUC900PDID W90X900_VA_GCR
41#define NUC910_CPUID 0x02900910
42#define NUC920_CPUID 0x02900920
43#define NUC950_CPUID 0x02900950
44#define NUC960_CPUID 0x02900960
45
46/* extern file from cpu.c */
47
48extern void nuc900_clock_source(struct device *dev, unsigned char *src);
49extern void nuc900_init_clocks(void);
50extern void nuc900_map_io(struct map_desc *mach_desc, int mach_size);
51extern void nuc900_board_init(struct platform_device **device, int size);
52
53/* for either public between 910 and 920, or between 920 and 950 */
54
55extern struct platform_device nuc900_serial_device;
56extern struct platform_device nuc900_device_fmi;
57extern struct platform_device nuc900_device_kpi;
58extern struct platform_device nuc900_device_rtc;
59extern struct platform_device nuc900_device_ts;
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
new file mode 100644
index 000000000000..2a6f98de48d2
--- /dev/null
+++ b/arch/arm/mach-w90x900/dev.c
@@ -0,0 +1,389 @@
1/*
2 * linux/arch/arm/mach-w90x900/dev.c
3 *
4 * Copyright (C) 2009 Nuvoton corporation.
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation;version 2 of the License.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/timer.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21
22#include <linux/mtd/physmap.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25
26#include <linux/spi/spi.h>
27#include <linux/spi/flash.h>
28
29#include <asm/mach/arch.h>
30#include <asm/mach/map.h>
31#include <asm/mach/irq.h>
32#include <asm/mach-types.h>
33
34#include <mach/regs-serial.h>
35#include <mach/map.h>
36
37#include "cpu.h"
38
39/*NUC900 evb norflash driver data */
40
41#define NUC900_FLASH_BASE 0xA0000000
42#define NUC900_FLASH_SIZE 0x400000
43#define SPIOFFSET 0x200
44#define SPIOREG_SIZE 0x100
45
46static struct mtd_partition nuc900_flash_partitions[] = {
47 {
48 .name = "NOR Partition 1 for kernel (960K)",
49 .size = 0xF0000,
50 .offset = 0x10000,
51 },
52 {
53 .name = "NOR Partition 2 for image (1M)",
54 .size = 0x100000,
55 .offset = 0x100000,
56 },
57 {
58 .name = "NOR Partition 3 for user (2M)",
59 .size = 0x200000,
60 .offset = 0x00200000,
61 }
62};
63
64static struct physmap_flash_data nuc900_flash_data = {
65 .width = 2,
66 .parts = nuc900_flash_partitions,
67 .nr_parts = ARRAY_SIZE(nuc900_flash_partitions),
68};
69
70static struct resource nuc900_flash_resources[] = {
71 {
72 .start = NUC900_FLASH_BASE,
73 .end = NUC900_FLASH_BASE + NUC900_FLASH_SIZE - 1,
74 .flags = IORESOURCE_MEM,
75 }
76};
77
78static struct platform_device nuc900_flash_device = {
79 .name = "physmap-flash",
80 .id = 0,
81 .dev = {
82 .platform_data = &nuc900_flash_data,
83 },
84 .resource = nuc900_flash_resources,
85 .num_resources = ARRAY_SIZE(nuc900_flash_resources),
86};
87
88/* USB EHCI Host Controller */
89
90static struct resource nuc900_usb_ehci_resource[] = {
91 [0] = {
92 .start = W90X900_PA_USBEHCIHOST,
93 .end = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
94 .flags = IORESOURCE_MEM,
95 },
96 [1] = {
97 .start = IRQ_USBH,
98 .end = IRQ_USBH,
99 .flags = IORESOURCE_IRQ,
100 }
101};
102
103static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL;
104
105static struct platform_device nuc900_device_usb_ehci = {
106 .name = "nuc900-ehci",
107 .id = -1,
108 .num_resources = ARRAY_SIZE(nuc900_usb_ehci_resource),
109 .resource = nuc900_usb_ehci_resource,
110 .dev = {
111 .dma_mask = &nuc900_device_usb_ehci_dmamask,
112 .coherent_dma_mask = 0xffffffffUL
113 }
114};
115
116/* USB OHCI Host Controller */
117
118static struct resource nuc900_usb_ohci_resource[] = {
119 [0] = {
120 .start = W90X900_PA_USBOHCIHOST,
121 .end = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
122 .flags = IORESOURCE_MEM,
123 },
124 [1] = {
125 .start = IRQ_USBH,
126 .end = IRQ_USBH,
127 .flags = IORESOURCE_IRQ,
128 }
129};
130
131static u64 nuc900_device_usb_ohci_dmamask = 0xffffffffUL;
132static struct platform_device nuc900_device_usb_ohci = {
133 .name = "nuc900-ohci",
134 .id = -1,
135 .num_resources = ARRAY_SIZE(nuc900_usb_ohci_resource),
136 .resource = nuc900_usb_ohci_resource,
137 .dev = {
138 .dma_mask = &nuc900_device_usb_ohci_dmamask,
139 .coherent_dma_mask = 0xffffffffUL
140 }
141};
142
143/* USB Device (Gadget)*/
144
145static struct resource nuc900_usbgadget_resource[] = {
146 [0] = {
147 .start = W90X900_PA_USBDEV,
148 .end = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
149 .flags = IORESOURCE_MEM,
150 },
151 [1] = {
152 .start = IRQ_USBD,
153 .end = IRQ_USBD,
154 .flags = IORESOURCE_IRQ,
155 }
156};
157
158static struct platform_device nuc900_device_usbgadget = {
159 .name = "nuc900-usbgadget",
160 .id = -1,
161 .num_resources = ARRAY_SIZE(nuc900_usbgadget_resource),
162 .resource = nuc900_usbgadget_resource,
163};
164
165/* MAC device */
166
167static struct resource nuc900_emc_resource[] = {
168 [0] = {
169 .start = W90X900_PA_EMC,
170 .end = W90X900_PA_EMC + W90X900_SZ_EMC - 1,
171 .flags = IORESOURCE_MEM,
172 },
173 [1] = {
174 .start = IRQ_EMCTX,
175 .end = IRQ_EMCTX,
176 .flags = IORESOURCE_IRQ,
177 },
178 [2] = {
179 .start = IRQ_EMCRX,
180 .end = IRQ_EMCRX,
181 .flags = IORESOURCE_IRQ,
182 }
183};
184
185static u64 nuc900_device_emc_dmamask = 0xffffffffUL;
186static struct platform_device nuc900_device_emc = {
187 .name = "nuc900-emc",
188 .id = -1,
189 .num_resources = ARRAY_SIZE(nuc900_emc_resource),
190 .resource = nuc900_emc_resource,
191 .dev = {
192 .dma_mask = &nuc900_device_emc_dmamask,
193 .coherent_dma_mask = 0xffffffffUL
194 }
195};
196
197/* SPI device */
198
199static struct resource nuc900_spi_resource[] = {
200 [0] = {
201 .start = W90X900_PA_I2C + SPIOFFSET,
202 .end = W90X900_PA_I2C + SPIOFFSET + SPIOREG_SIZE - 1,
203 .flags = IORESOURCE_MEM,
204 },
205 [1] = {
206 .start = IRQ_SSP,
207 .end = IRQ_SSP,
208 .flags = IORESOURCE_IRQ,
209 }
210};
211
212static struct platform_device nuc900_device_spi = {
213 .name = "nuc900-spi",
214 .id = -1,
215 .num_resources = ARRAY_SIZE(nuc900_spi_resource),
216 .resource = nuc900_spi_resource,
217};
218
219/* spi device, spi flash info */
220
221static struct mtd_partition nuc900_spi_flash_partitions[] = {
222 {
223 .name = "bootloader(spi)",
224 .size = 0x0100000,
225 .offset = 0,
226 },
227};
228
229static struct flash_platform_data nuc900_spi_flash_data = {
230 .name = "m25p80",
231 .parts = nuc900_spi_flash_partitions,
232 .nr_parts = ARRAY_SIZE(nuc900_spi_flash_partitions),
233 .type = "w25x16",
234};
235
236static struct spi_board_info nuc900_spi_board_info[] __initdata = {
237 {
238 .modalias = "m25p80",
239 .max_speed_hz = 20000000,
240 .bus_num = 0,
241 .chip_select = 1,
242 .platform_data = &nuc900_spi_flash_data,
243 .mode = SPI_MODE_0,
244 },
245};
246
247/* WDT Device */
248
249static struct resource nuc900_wdt_resource[] = {
250 [0] = {
251 .start = W90X900_PA_TIMER,
252 .end = W90X900_PA_TIMER + W90X900_SZ_TIMER - 1,
253 .flags = IORESOURCE_MEM,
254 },
255 [1] = {
256 .start = IRQ_WDT,
257 .end = IRQ_WDT,
258 .flags = IORESOURCE_IRQ,
259 }
260};
261
262static struct platform_device nuc900_device_wdt = {
263 .name = "nuc900-wdt",
264 .id = -1,
265 .num_resources = ARRAY_SIZE(nuc900_wdt_resource),
266 .resource = nuc900_wdt_resource,
267};
268
269/*
270 * public device definition between 910 and 920, or 910
271 * and 950 or 950 and 960...,their dev platform register
272 * should be in specific file such as nuc950, nuc960 c
273 * files rather than the public dev.c file here. so the
274 * corresponding platform_device definition should not be
275 * static.
276*/
277
278/* RTC controller*/
279
280static struct resource nuc900_rtc_resource[] = {
281 [0] = {
282 .start = W90X900_PA_RTC,
283 .end = W90X900_PA_RTC + 0xff,
284 .flags = IORESOURCE_MEM,
285 },
286 [1] = {
287 .start = IRQ_RTC,
288 .end = IRQ_RTC,
289 .flags = IORESOURCE_IRQ,
290 },
291};
292
293struct platform_device nuc900_device_rtc = {
294 .name = "nuc900-rtc",
295 .id = -1,
296 .num_resources = ARRAY_SIZE(nuc900_rtc_resource),
297 .resource = nuc900_rtc_resource,
298};
299
300/*TouchScreen controller*/
301
302static struct resource nuc900_ts_resource[] = {
303 [0] = {
304 .start = W90X900_PA_ADC,
305 .end = W90X900_PA_ADC + W90X900_SZ_ADC-1,
306 .flags = IORESOURCE_MEM,
307 },
308 [1] = {
309 .start = IRQ_ADC,
310 .end = IRQ_ADC,
311 .flags = IORESOURCE_IRQ,
312 },
313};
314
315struct platform_device nuc900_device_ts = {
316 .name = "nuc900-ts",
317 .id = -1,
318 .resource = nuc900_ts_resource,
319 .num_resources = ARRAY_SIZE(nuc900_ts_resource),
320};
321
322/* FMI Device */
323
324static struct resource nuc900_fmi_resource[] = {
325 [0] = {
326 .start = W90X900_PA_FMI,
327 .end = W90X900_PA_FMI + W90X900_SZ_FMI - 1,
328 .flags = IORESOURCE_MEM,
329 },
330 [1] = {
331 .start = IRQ_FMI,
332 .end = IRQ_FMI,
333 .flags = IORESOURCE_IRQ,
334 }
335};
336
337struct platform_device nuc900_device_fmi = {
338 .name = "nuc900-fmi",
339 .id = -1,
340 .num_resources = ARRAY_SIZE(nuc900_fmi_resource),
341 .resource = nuc900_fmi_resource,
342};
343
344/* KPI controller*/
345
346static struct resource nuc900_kpi_resource[] = {
347 [0] = {
348 .start = W90X900_PA_KPI,
349 .end = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
350 .flags = IORESOURCE_MEM,
351 },
352 [1] = {
353 .start = IRQ_KPI,
354 .end = IRQ_KPI,
355 .flags = IORESOURCE_IRQ,
356 }
357
358};
359
360struct platform_device nuc900_device_kpi = {
361 .name = "nuc900-kpi",
362 .id = -1,
363 .num_resources = ARRAY_SIZE(nuc900_kpi_resource),
364 .resource = nuc900_kpi_resource,
365};
366
367/*Here should be your evb resourse,such as LCD*/
368
369static struct platform_device *nuc900_public_dev[] __initdata = {
370 &nuc900_serial_device,
371 &nuc900_flash_device,
372 &nuc900_device_usb_ehci,
373 &nuc900_device_usb_ohci,
374 &nuc900_device_usbgadget,
375 &nuc900_device_emc,
376 &nuc900_device_spi,
377 &nuc900_device_wdt,
378};
379
380/* Provide adding specific CPU platform devices API */
381
382void __init nuc900_board_init(struct platform_device **device, int size)
383{
384 platform_add_devices(device, size);
385 platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
386 spi_register_board_info(nuc900_spi_board_info,
387 ARRAY_SIZE(nuc900_spi_board_info));
388}
389
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c
index c72e0dfa1825..ba05aec7ea4b 100644
--- a/arch/arm/mach-w90x900/gpio.c
+++ b/arch/arm/mach-w90x900/gpio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/arch/arm/mach-w90p910/gpio.c 2 * linux/arch/arm/mach-w90x900/gpio.c
3 * 3 *
4 * Generic w90p910 GPIO handling 4 * Generic nuc900 GPIO handling
5 * 5 *
6 * Wan ZongShun <mcuos.com@gmail.com> 6 * Wan ZongShun <mcuos.com@gmail.com>
7 * 7 *
@@ -30,31 +30,31 @@
30#define GPIO_IN (0x0C) 30#define GPIO_IN (0x0C)
31#define GROUPINERV (0x10) 31#define GROUPINERV (0x10)
32#define GPIO_GPIO(Nb) (0x00000001 << (Nb)) 32#define GPIO_GPIO(Nb) (0x00000001 << (Nb))
33#define to_w90p910_gpio_chip(c) container_of(c, struct w90p910_gpio_chip, chip) 33#define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip)
34 34
35#define W90P910_GPIO_CHIP(name, base_gpio, nr_gpio) \ 35#define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio) \
36 { \ 36 { \
37 .chip = { \ 37 .chip = { \
38 .label = name, \ 38 .label = name, \
39 .direction_input = w90p910_dir_input, \ 39 .direction_input = nuc900_dir_input, \
40 .direction_output = w90p910_dir_output, \ 40 .direction_output = nuc900_dir_output, \
41 .get = w90p910_gpio_get, \ 41 .get = nuc900_gpio_get, \
42 .set = w90p910_gpio_set, \ 42 .set = nuc900_gpio_set, \
43 .base = base_gpio, \ 43 .base = base_gpio, \
44 .ngpio = nr_gpio, \ 44 .ngpio = nr_gpio, \
45 } \ 45 } \
46 } 46 }
47 47
48struct w90p910_gpio_chip { 48struct nuc900_gpio_chip {
49 struct gpio_chip chip; 49 struct gpio_chip chip;
50 void __iomem *regbase; /* Base of group register*/ 50 void __iomem *regbase; /* Base of group register*/
51 spinlock_t gpio_lock; 51 spinlock_t gpio_lock;
52}; 52};
53 53
54static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset) 54static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
55{ 55{
56 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); 56 struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
57 void __iomem *pio = w90p910_gpio->regbase + GPIO_IN; 57 void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
58 unsigned int regval; 58 unsigned int regval;
59 59
60 regval = __raw_readl(pio); 60 regval = __raw_readl(pio);
@@ -63,14 +63,14 @@ static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset)
63 return (regval != 0); 63 return (regval != 0);
64} 64}
65 65
66static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val) 66static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
67{ 67{
68 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); 68 struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
69 void __iomem *pio = w90p910_gpio->regbase + GPIO_OUT; 69 void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
70 unsigned int regval; 70 unsigned int regval;
71 unsigned long flags; 71 unsigned long flags;
72 72
73 spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags); 73 spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
74 74
75 regval = __raw_readl(pio); 75 regval = __raw_readl(pio);
76 76
@@ -81,36 +81,36 @@ static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
81 81
82 __raw_writel(regval, pio); 82 __raw_writel(regval, pio);
83 83
84 spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags); 84 spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
85} 85}
86 86
87static int w90p910_dir_input(struct gpio_chip *chip, unsigned offset) 87static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
88{ 88{
89 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); 89 struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
90 void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR; 90 void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
91 unsigned int regval; 91 unsigned int regval;
92 unsigned long flags; 92 unsigned long flags;
93 93
94 spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags); 94 spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
95 95
96 regval = __raw_readl(pio); 96 regval = __raw_readl(pio);
97 regval &= ~GPIO_GPIO(offset); 97 regval &= ~GPIO_GPIO(offset);
98 __raw_writel(regval, pio); 98 __raw_writel(regval, pio);
99 99
100 spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags); 100 spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
101 101
102 return 0; 102 return 0;
103} 103}
104 104
105static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val) 105static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
106{ 106{
107 struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); 107 struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
108 void __iomem *outreg = w90p910_gpio->regbase + GPIO_OUT; 108 void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
109 void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR; 109 void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
110 unsigned int regval; 110 unsigned int regval;
111 unsigned long flags; 111 unsigned long flags;
112 112
113 spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags); 113 spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
114 114
115 regval = __raw_readl(pio); 115 regval = __raw_readl(pio);
116 regval |= GPIO_GPIO(offset); 116 regval |= GPIO_GPIO(offset);
@@ -125,28 +125,28 @@ static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val)
125 125
126 __raw_writel(regval, outreg); 126 __raw_writel(regval, outreg);
127 127
128 spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags); 128 spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
129 129
130 return 0; 130 return 0;
131} 131}
132 132
133static struct w90p910_gpio_chip w90p910_gpio[] = { 133static struct nuc900_gpio_chip nuc900_gpio[] = {
134 W90P910_GPIO_CHIP("GROUPC", 0, 16), 134 NUC900_GPIO_CHIP("GROUPC", 0, 16),
135 W90P910_GPIO_CHIP("GROUPD", 16, 10), 135 NUC900_GPIO_CHIP("GROUPD", 16, 10),
136 W90P910_GPIO_CHIP("GROUPE", 26, 14), 136 NUC900_GPIO_CHIP("GROUPE", 26, 14),
137 W90P910_GPIO_CHIP("GROUPF", 40, 10), 137 NUC900_GPIO_CHIP("GROUPF", 40, 10),
138 W90P910_GPIO_CHIP("GROUPG", 50, 17), 138 NUC900_GPIO_CHIP("GROUPG", 50, 17),
139 W90P910_GPIO_CHIP("GROUPH", 67, 8), 139 NUC900_GPIO_CHIP("GROUPH", 67, 8),
140 W90P910_GPIO_CHIP("GROUPI", 75, 17), 140 NUC900_GPIO_CHIP("GROUPI", 75, 17),
141}; 141};
142 142
143void __init w90p910_init_gpio(int nr_group) 143void __init nuc900_init_gpio(int nr_group)
144{ 144{
145 unsigned i; 145 unsigned i;
146 struct w90p910_gpio_chip *gpio_chip; 146 struct nuc900_gpio_chip *gpio_chip;
147 147
148 for (i = 0; i < nr_group; i++) { 148 for (i = 0; i < nr_group; i++) {
149 gpio_chip = &w90p910_gpio[i]; 149 gpio_chip = &nuc900_gpio[i];
150 spin_lock_init(&gpio_chip->gpio_lock); 150 spin_lock_init(&gpio_chip->gpio_lock);
151 gpio_chip->regbase = GPIO_BASE + i * GROUPINERV; 151 gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
152 gpiochip_add(&gpio_chip->chip); 152 gpiochip_add(&gpio_chip->chip);
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h
index f10b6a8dc069..516d6b477b61 100644
--- a/arch/arm/mach-w90x900/include/mach/regs-clock.h
+++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h
@@ -28,4 +28,26 @@
28#define REG_CLKEN1 (CLK_BA + 0x24) 28#define REG_CLKEN1 (CLK_BA + 0x24)
29#define REG_CLKDIV1 (CLK_BA + 0x28) 29#define REG_CLKDIV1 (CLK_BA + 0x28)
30 30
31/* Define PLL freq setting */
32#define PLL_DISABLE 0x12B63
33#define PLL_66MHZ 0x2B63
34#define PLL_100MHZ 0x4F64
35#define PLL_120MHZ 0x4F63
36#define PLL_166MHZ 0x4124
37#define PLL_200MHZ 0x4F24
38
39/* Define AHB:CPUFREQ ratio */
40#define AHB_CPUCLK_1_1 0x00
41#define AHB_CPUCLK_1_2 0x01
42#define AHB_CPUCLK_1_4 0x02
43#define AHB_CPUCLK_1_8 0x03
44
45/* Define APB:AHB ratio */
46#define APB_AHB_1_2 0x01
47#define APB_AHB_1_4 0x02
48#define APB_AHB_1_8 0x03
49
50/* Define clock skew */
51#define DEFAULTSKEW 0x48
52
31#endif /* __ASM_ARCH_REGS_CLOCK_H */ 53#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
new file mode 100644
index 000000000000..b68455e7f88b
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
@@ -0,0 +1,33 @@
1/*
2 * arch/arm/mach-w90x900/include/mach/regs-ebi.h
3 *
4 * Copyright (c) 2009 Nuvoton technology corporation.
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation;version 2 of the License.
11 *
12 */
13
14#ifndef __ASM_ARCH_REGS_EBI_H
15#define __ASM_ARCH_REGS_EBI_H
16
17/* EBI Control Registers */
18
19#define EBI_BA W90X900_VA_EBI
20#define REG_EBICON (EBI_BA + 0x00)
21#define REG_ROMCON (EBI_BA + 0x04)
22#define REG_SDCONF0 (EBI_BA + 0x08)
23#define REG_SDCONF1 (EBI_BA + 0x0C)
24#define REG_SDTIME0 (EBI_BA + 0x10)
25#define REG_SDTIME1 (EBI_BA + 0x14)
26#define REG_EXT0CON (EBI_BA + 0x18)
27#define REG_EXT1CON (EBI_BA + 0x1C)
28#define REG_EXT2CON (EBI_BA + 0x20)
29#define REG_EXT3CON (EBI_BA + 0x24)
30#define REG_EXT4CON (EBI_BA + 0x28)
31#define REG_CKSKEW (EBI_BA + 0x2C)
32
33#endif /* __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
new file mode 100644
index 000000000000..556778e8ddaa
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
@@ -0,0 +1,15 @@
1#ifndef __ASM_ARCH_W90P910_KEYPAD_H
2#define __ASM_ARCH_W90P910_KEYPAD_H
3
4#include <linux/input/matrix_keypad.h>
5
6extern void mfp_set_groupi(struct device *dev);
7
8struct w90p910_keypad_platform_data {
9 const struct matrix_keymap_data *keymap_data;
10
11 unsigned int prescale;
12 unsigned int debounce;
13};
14
15#endif /* __ASM_ARCH_W90P910_KEYPAD_H */
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
index 0b4fc194729c..0ce9d8e867eb 100644
--- a/arch/arm/mach-w90x900/irq.c
+++ b/arch/arm/mach-w90x900/irq.c
@@ -10,8 +10,7 @@
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation;version 2 of the License.
14 * (at your option) any later version.
15 * 14 *
16 */ 15 */
17 16
@@ -29,9 +28,114 @@
29#include <mach/hardware.h> 28#include <mach/hardware.h>
30#include <mach/regs-irq.h> 29#include <mach/regs-irq.h>
31 30
32static void w90x900_irq_mask(unsigned int irq) 31struct group_irq {
32 unsigned long gpen;
33 unsigned int enabled;
34 void (*enable)(struct group_irq *, int enable);
35};
36
37static DEFINE_SPINLOCK(groupirq_lock);
38
39#define DEFINE_GROUP(_name, _ctrlbit, _num) \
40struct group_irq group_##_name = { \
41 .enable = nuc900_group_enable, \
42 .gpen = ((1 << _num) - 1) << _ctrlbit, \
43 }
44
45static void nuc900_group_enable(struct group_irq *gpirq, int enable);
46
47static DEFINE_GROUP(nirq0, 0, 4);
48static DEFINE_GROUP(nirq1, 4, 4);
49static DEFINE_GROUP(usbh, 8, 2);
50static DEFINE_GROUP(ottimer, 16, 3);
51static DEFINE_GROUP(gdma, 20, 2);
52static DEFINE_GROUP(sc, 24, 2);
53static DEFINE_GROUP(i2c, 26, 2);
54static DEFINE_GROUP(ps2, 28, 2);
55
56static int group_irq_enable(struct group_irq *group_irq)
57{
58 unsigned long flags;
59
60 spin_lock_irqsave(&groupirq_lock, flags);
61 if (group_irq->enabled++ == 0)
62 (group_irq->enable)(group_irq, 1);
63 spin_unlock_irqrestore(&groupirq_lock, flags);
64
65 return 0;
66}
67
68static void group_irq_disable(struct group_irq *group_irq)
33{ 69{
70 unsigned long flags;
71
72 WARN_ON(group_irq->enabled == 0);
73
74 spin_lock_irqsave(&groupirq_lock, flags);
75 if (--group_irq->enabled == 0)
76 (group_irq->enable)(group_irq, 0);
77 spin_unlock_irqrestore(&groupirq_lock, flags);
78}
79
80static void nuc900_group_enable(struct group_irq *gpirq, int enable)
81{
82 unsigned int groupen = gpirq->gpen;
83 unsigned long regval;
84
85 regval = __raw_readl(REG_AIC_GEN);
86
87 if (enable)
88 regval |= groupen;
89 else
90 regval &= ~groupen;
91
92 __raw_writel(regval, REG_AIC_GEN);
93}
94
95static void nuc900_irq_mask(unsigned int irq)
96{
97 struct group_irq *group_irq;
98
99 group_irq = NULL;
100
34 __raw_writel(1 << irq, REG_AIC_MDCR); 101 __raw_writel(1 << irq, REG_AIC_MDCR);
102
103 switch (irq) {
104 case IRQ_GROUP0:
105 group_irq = &group_nirq0;
106 break;
107
108 case IRQ_GROUP1:
109 group_irq = &group_nirq1;
110 break;
111
112 case IRQ_USBH:
113 group_irq = &group_usbh;
114 break;
115
116 case IRQ_T_INT_GROUP:
117 group_irq = &group_ottimer;
118 break;
119
120 case IRQ_GDMAGROUP:
121 group_irq = &group_gdma;
122 break;
123
124 case IRQ_SCGROUP:
125 group_irq = &group_sc;
126 break;
127
128 case IRQ_I2CGROUP:
129 group_irq = &group_i2c;
130 break;
131
132 case IRQ_P2SGROUP:
133 group_irq = &group_ps2;
134 break;
135 }
136
137 if (group_irq)
138 group_irq_disable(group_irq);
35} 139}
36 140
37/* 141/*
@@ -39,37 +143,71 @@ static void w90x900_irq_mask(unsigned int irq)
39 * to REG_AIC_EOSCR for ACK 143 * to REG_AIC_EOSCR for ACK
40 */ 144 */
41 145
42static void w90x900_irq_ack(unsigned int irq) 146static void nuc900_irq_ack(unsigned int irq)
43{ 147{
44 __raw_writel(0x01, REG_AIC_EOSCR); 148 __raw_writel(0x01, REG_AIC_EOSCR);
45} 149}
46 150
47static void w90x900_irq_unmask(unsigned int irq) 151static void nuc900_irq_unmask(unsigned int irq)
48{ 152{
49 unsigned long mask; 153 struct group_irq *group_irq;
154
155 group_irq = NULL;
50 156
51 if (irq == IRQ_T_INT_GROUP) {
52 mask = __raw_readl(REG_AIC_GEN);
53 __raw_writel(TIME_GROUP_IRQ | mask, REG_AIC_GEN);
54 __raw_writel(1 << IRQ_T_INT_GROUP, REG_AIC_MECR);
55 }
56 __raw_writel(1 << irq, REG_AIC_MECR); 157 __raw_writel(1 << irq, REG_AIC_MECR);
158
159 switch (irq) {
160 case IRQ_GROUP0:
161 group_irq = &group_nirq0;
162 break;
163
164 case IRQ_GROUP1:
165 group_irq = &group_nirq1;
166 break;
167
168 case IRQ_USBH:
169 group_irq = &group_usbh;
170 break;
171
172 case IRQ_T_INT_GROUP:
173 group_irq = &group_ottimer;
174 break;
175
176 case IRQ_GDMAGROUP:
177 group_irq = &group_gdma;
178 break;
179
180 case IRQ_SCGROUP:
181 group_irq = &group_sc;
182 break;
183
184 case IRQ_I2CGROUP:
185 group_irq = &group_i2c;
186 break;
187
188 case IRQ_P2SGROUP:
189 group_irq = &group_ps2;
190 break;
191 }
192
193 if (group_irq)
194 group_irq_enable(group_irq);
57} 195}
58 196
59static struct irq_chip w90x900_irq_chip = { 197static struct irq_chip nuc900_irq_chip = {
60 .ack = w90x900_irq_ack, 198 .ack = nuc900_irq_ack,
61 .mask = w90x900_irq_mask, 199 .mask = nuc900_irq_mask,
62 .unmask = w90x900_irq_unmask, 200 .unmask = nuc900_irq_unmask,
63}; 201};
64 202
65void __init w90x900_init_irq(void) 203void __init nuc900_init_irq(void)
66{ 204{
67 int irqno; 205 int irqno;
68 206
69 __raw_writel(0xFFFFFFFE, REG_AIC_MDCR); 207 __raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
70 208
71 for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) { 209 for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) {
72 set_irq_chip(irqno, &w90x900_irq_chip); 210 set_irq_chip(irqno, &nuc900_irq_chip);
73 set_irq_handler(irqno, handle_level_irq); 211 set_irq_handler(irqno, handle_level_irq);
74 set_irq_flags(irqno, IRQF_VALID); 212 set_irq_flags(irqno, IRQF_VALID);
75 } 213 }
diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c
new file mode 100644
index 000000000000..ec05bda946f3
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc910evb.c
@@ -0,0 +1,44 @@
1/*
2 * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
3 *
4 * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
5 *
6 * Copyright (C) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation;version 2 of the License.
13 *
14 */
15
16#include <linux/platform_device.h>
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <asm/mach-types.h>
20#include <mach/map.h>
21
22#include "nuc910.h"
23
24static void __init nuc910evb_map_io(void)
25{
26 nuc910_map_io();
27 nuc910_init_clocks();
28}
29
30static void __init nuc910evb_init(void)
31{
32 nuc910_board_init();
33}
34
35MACHINE_START(W90P910EVB, "W90P910EVB")
36 /* Maintainer: Wan ZongShun */
37 .phys_io = W90X900_PA_UART,
38 .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
39 .boot_params = 0,
40 .map_io = nuc910evb_map_io,
41 .init_irq = nuc900_init_irq,
42 .init_machine = nuc910evb_init,
43 .timer = &nuc900_timer,
44MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
new file mode 100644
index 000000000000..cef903bcccd1
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc950evb.c
@@ -0,0 +1,44 @@
1/*
2 * linux/arch/arm/mach-w90x900/mach-nuc950evb.c
3 *
4 * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
5 *
6 * Copyright (C) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation;version 2 of the License.
13 *
14 */
15
16#include <linux/platform_device.h>
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <asm/mach-types.h>
20#include <mach/map.h>
21
22#include "nuc950.h"
23
24static void __init nuc950evb_map_io(void)
25{
26 nuc950_map_io();
27 nuc950_init_clocks();
28}
29
30static void __init nuc950evb_init(void)
31{
32 nuc950_board_init();
33}
34
35MACHINE_START(W90P950EVB, "W90P950EVB")
36 /* Maintainer: Wan ZongShun */
37 .phys_io = W90X900_PA_UART,
38 .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
39 .boot_params = 0,
40 .map_io = nuc950evb_map_io,
41 .init_irq = nuc900_init_irq,
42 .init_machine = nuc950evb_init,
43 .timer = &nuc900_timer,
44MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c
new file mode 100644
index 000000000000..e3a46f19f2bc
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc960evb.c
@@ -0,0 +1,44 @@
1/*
2 * linux/arch/arm/mach-w90x900/mach-nuc960evb.c
3 *
4 * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
5 *
6 * Copyright (C) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation;version 2 of the License.
13 *
14 */
15
16#include <linux/platform_device.h>
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <asm/mach-types.h>
20#include <mach/map.h>
21
22#include "nuc960.h"
23
24static void __init nuc960evb_map_io(void)
25{
26 nuc960_map_io();
27 nuc960_init_clocks();
28}
29
30static void __init nuc960evb_init(void)
31{
32 nuc960_board_init();
33}
34
35MACHINE_START(W90N960EVB, "W90N960EVB")
36 /* Maintainer: Wan ZongShun */
37 .phys_io = W90X900_PA_UART,
38 .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
39 .boot_params = 0,
40 .map_io = nuc960evb_map_io,
41 .init_irq = nuc900_init_irq,
42 .init_machine = nuc960evb_init,
43 .timer = &nuc900_timer,
44MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c
deleted file mode 100644
index 7a62bd348e80..000000000000
--- a/arch/arm/mach-w90x900/mach-w90p910evb.c
+++ /dev/null
@@ -1,267 +0,0 @@
1/*
2 * linux/arch/arm/mach-w90x900/mach-w90p910evb.c
3 *
4 * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
5 *
6 * Copyright (C) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation;version 2 of the License.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/interrupt.h>
19#include <linux/list.h>
20#include <linux/timer.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/mtd/physmap.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/irq.h>
28#include <asm/mach-types.h>
29
30#include <mach/regs-serial.h>
31#include <mach/map.h>
32
33#include "cpu.h"
34/*w90p910 evb norflash driver data */
35
36#define W90P910_FLASH_BASE 0xA0000000
37#define W90P910_FLASH_SIZE 0x400000
38
39static struct mtd_partition w90p910_flash_partitions[] = {
40 {
41 .name = "NOR Partition 1 for kernel (960K)",
42 .size = 0xF0000,
43 .offset = 0x10000,
44 },
45 {
46 .name = "NOR Partition 2 for image (1M)",
47 .size = 0x100000,
48 .offset = 0x100000,
49 },
50 {
51 .name = "NOR Partition 3 for user (2M)",
52 .size = 0x200000,
53 .offset = 0x00200000,
54 }
55};
56
57static struct physmap_flash_data w90p910_flash_data = {
58 .width = 2,
59 .parts = w90p910_flash_partitions,
60 .nr_parts = ARRAY_SIZE(w90p910_flash_partitions),
61};
62
63static struct resource w90p910_flash_resources[] = {
64 {
65 .start = W90P910_FLASH_BASE,
66 .end = W90P910_FLASH_BASE + W90P910_FLASH_SIZE - 1,
67 .flags = IORESOURCE_MEM,
68 }
69};
70
71static struct platform_device w90p910_flash_device = {
72 .name = "physmap-flash",
73 .id = 0,
74 .dev = {
75 .platform_data = &w90p910_flash_data,
76 },
77 .resource = w90p910_flash_resources,
78 .num_resources = ARRAY_SIZE(w90p910_flash_resources),
79};
80
81/* USB EHCI Host Controller */
82
83static struct resource w90x900_usb_ehci_resource[] = {
84 [0] = {
85 .start = W90X900_PA_USBEHCIHOST,
86 .end = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
87 .flags = IORESOURCE_MEM,
88 },
89 [1] = {
90 .start = IRQ_USBH,
91 .end = IRQ_USBH,
92 .flags = IORESOURCE_IRQ,
93 }
94};
95
96static u64 w90x900_device_usb_ehci_dmamask = 0xffffffffUL;
97
98struct platform_device w90x900_device_usb_ehci = {
99 .name = "w90x900-ehci",
100 .id = -1,
101 .num_resources = ARRAY_SIZE(w90x900_usb_ehci_resource),
102 .resource = w90x900_usb_ehci_resource,
103 .dev = {
104 .dma_mask = &w90x900_device_usb_ehci_dmamask,
105 .coherent_dma_mask = 0xffffffffUL
106 }
107};
108EXPORT_SYMBOL(w90x900_device_usb_ehci);
109
110/* USB OHCI Host Controller */
111
112static struct resource w90x900_usb_ohci_resource[] = {
113 [0] = {
114 .start = W90X900_PA_USBOHCIHOST,
115 .end = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
116 .flags = IORESOURCE_MEM,
117 },
118 [1] = {
119 .start = IRQ_USBH,
120 .end = IRQ_USBH,
121 .flags = IORESOURCE_IRQ,
122 }
123};
124
125static u64 w90x900_device_usb_ohci_dmamask = 0xffffffffUL;
126struct platform_device w90x900_device_usb_ohci = {
127 .name = "w90x900-ohci",
128 .id = -1,
129 .num_resources = ARRAY_SIZE(w90x900_usb_ohci_resource),
130 .resource = w90x900_usb_ohci_resource,
131 .dev = {
132 .dma_mask = &w90x900_device_usb_ohci_dmamask,
133 .coherent_dma_mask = 0xffffffffUL
134 }
135};
136EXPORT_SYMBOL(w90x900_device_usb_ohci);
137
138/*TouchScreen controller*/
139
140static struct resource w90x900_ts_resource[] = {
141 [0] = {
142 .start = W90X900_PA_ADC,
143 .end = W90X900_PA_ADC + W90X900_SZ_ADC-1,
144 .flags = IORESOURCE_MEM,
145 },
146 [1] = {
147 .start = IRQ_ADC,
148 .end = IRQ_ADC,
149 .flags = IORESOURCE_IRQ,
150 },
151};
152
153struct platform_device w90x900_device_ts = {
154 .name = "w90x900-ts",
155 .id = -1,
156 .resource = w90x900_ts_resource,
157 .num_resources = ARRAY_SIZE(w90x900_ts_resource),
158};
159EXPORT_SYMBOL(w90x900_device_ts);
160
161/* RTC controller*/
162
163static struct resource w90x900_rtc_resource[] = {
164 [0] = {
165 .start = W90X900_PA_RTC,
166 .end = W90X900_PA_RTC + 0xff,
167 .flags = IORESOURCE_MEM,
168 },
169 [1] = {
170 .start = IRQ_RTC,
171 .end = IRQ_RTC,
172 .flags = IORESOURCE_IRQ,
173 },
174};
175
176struct platform_device w90x900_device_rtc = {
177 .name = "w90x900-rtc",
178 .id = -1,
179 .num_resources = ARRAY_SIZE(w90x900_rtc_resource),
180 .resource = w90x900_rtc_resource,
181};
182EXPORT_SYMBOL(w90x900_device_rtc);
183
184/* KPI controller*/
185
186static struct resource w90x900_kpi_resource[] = {
187 [0] = {
188 .start = W90X900_PA_KPI,
189 .end = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
190 .flags = IORESOURCE_MEM,
191 },
192 [1] = {
193 .start = IRQ_KPI,
194 .end = IRQ_KPI,
195 .flags = IORESOURCE_IRQ,
196 }
197
198};
199
200struct platform_device w90x900_device_kpi = {
201 .name = "w90x900-kpi",
202 .id = -1,
203 .num_resources = ARRAY_SIZE(w90x900_kpi_resource),
204 .resource = w90x900_kpi_resource,
205};
206EXPORT_SYMBOL(w90x900_device_kpi);
207
208/* USB Device (Gadget)*/
209
210static struct resource w90x900_usbgadget_resource[] = {
211 [0] = {
212 .start = W90X900_PA_USBDEV,
213 .end = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
214 .flags = IORESOURCE_MEM,
215 },
216 [1] = {
217 .start = IRQ_USBD,
218 .end = IRQ_USBD,
219 .flags = IORESOURCE_IRQ,
220 }
221};
222
223struct platform_device w90x900_device_usbgadget = {
224 .name = "w90x900-usbgadget",
225 .id = -1,
226 .num_resources = ARRAY_SIZE(w90x900_usbgadget_resource),
227 .resource = w90x900_usbgadget_resource,
228};
229EXPORT_SYMBOL(w90x900_device_usbgadget);
230
231static struct map_desc w90p910_iodesc[] __initdata = {
232};
233
234/*Here should be your evb resourse,such as LCD*/
235
236static struct platform_device *w90p910evb_dev[] __initdata = {
237 &w90p910_serial_device,
238 &w90p910_flash_device,
239 &w90x900_device_usb_ehci,
240 &w90x900_device_usb_ohci,
241 &w90x900_device_ts,
242 &w90x900_device_rtc,
243 &w90x900_device_kpi,
244 &w90x900_device_usbgadget,
245};
246
247static void __init w90p910evb_map_io(void)
248{
249 w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
250 w90p910_init_clocks();
251}
252
253static void __init w90p910evb_init(void)
254{
255 platform_add_devices(w90p910evb_dev, ARRAY_SIZE(w90p910evb_dev));
256}
257
258MACHINE_START(W90P910EVB, "W90P910EVB")
259 /* Maintainer: Wan ZongShun */
260 .phys_io = W90X900_PA_UART,
261 .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
262 .boot_params = 0,
263 .map_io = w90p910evb_map_io,
264 .init_irq = w90x900_init_irq,
265 .init_machine = w90p910evb_init,
266 .timer = &w90x900_timer,
267MACHINE_END
diff --git a/arch/arm/mach-w90x900/mfp-w90p910.c b/arch/arm/mach-w90x900/mfp-w90p910.c
deleted file mode 100644
index a3520fefb5e7..000000000000
--- a/arch/arm/mach-w90x900/mfp-w90p910.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * linux/arch/arm/mach-w90x900/mfp-w90p910.c
3 *
4 * Copyright (c) 2008 Nuvoton technology corporation
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation;version 2 of the License.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/string.h>
20#include <linux/clk.h>
21#include <linux/mutex.h>
22#include <linux/io.h>
23
24#include <mach/hardware.h>
25
26#define REG_MFSEL (W90X900_VA_GCR + 0xC)
27
28#define GPSELF (0x01 << 1)
29
30#define GPSELC (0x03 << 2)
31#define ENKPI (0x02 << 2)
32#define ENNAND (0x01 << 2)
33
34#define GPSELEI0 (0x01 << 26)
35#define GPSELEI1 (0x01 << 27)
36
37static DECLARE_MUTEX(mfp_sem);
38
39void mfp_set_groupf(struct device *dev)
40{
41 unsigned long mfpen;
42 const char *dev_id;
43
44 BUG_ON(!dev);
45
46 down(&mfp_sem);
47
48 dev_id = dev_name(dev);
49
50 mfpen = __raw_readl(REG_MFSEL);
51
52 if (strcmp(dev_id, "w90p910-emc") == 0)
53 mfpen |= GPSELF;/*enable mac*/
54 else
55 mfpen &= ~GPSELF;/*GPIOF[9:0]*/
56
57 __raw_writel(mfpen, REG_MFSEL);
58
59 up(&mfp_sem);
60}
61EXPORT_SYMBOL(mfp_set_groupf);
62
63void mfp_set_groupc(struct device *dev)
64{
65 unsigned long mfpen;
66 const char *dev_id;
67
68 BUG_ON(!dev);
69
70 down(&mfp_sem);
71
72 dev_id = dev_name(dev);
73
74 mfpen = __raw_readl(REG_MFSEL);
75
76 if (strcmp(dev_id, "w90p910-lcd") == 0)
77 mfpen |= GPSELC;/*enable lcd*/
78 else if (strcmp(dev_id, "w90p910-kpi") == 0) {
79 mfpen &= (~GPSELC);/*enable kpi*/
80 mfpen |= ENKPI;
81 } else if (strcmp(dev_id, "w90p910-nand") == 0) {
82 mfpen &= (~GPSELC);/*enable nand*/
83 mfpen |= ENNAND;
84 } else
85 mfpen &= (~GPSELC);/*GPIOC[14:0]*/
86
87 __raw_writel(mfpen, REG_MFSEL);
88
89 up(&mfp_sem);
90}
91EXPORT_SYMBOL(mfp_set_groupc);
92
93void mfp_set_groupi(struct device *dev, int gpio)
94{
95 unsigned long mfpen;
96 const char *dev_id;
97
98 BUG_ON(!dev);
99
100 down(&mfp_sem);
101
102 dev_id = dev_name(dev);
103
104 mfpen = __raw_readl(REG_MFSEL);
105
106 if (strcmp(dev_id, "w90p910-wdog") == 0)
107 mfpen |= GPSELEI1;/*enable wdog*/
108 else if (strcmp(dev_id, "w90p910-atapi") == 0)
109 mfpen |= GPSELEI0;/*enable atapi*/
110
111 __raw_writel(mfpen, REG_MFSEL);
112
113 up(&mfp_sem);
114}
115EXPORT_SYMBOL(mfp_set_groupi);
116
diff --git a/arch/arm/mach-w90x900/mfp.c b/arch/arm/mach-w90x900/mfp.c
new file mode 100644
index 000000000000..a47dc9a708ee
--- /dev/null
+++ b/arch/arm/mach-w90x900/mfp.c
@@ -0,0 +1,158 @@
1/*
2 * linux/arch/arm/mach-w90x900/mfp.c
3 *
4 * Copyright (c) 2008 Nuvoton technology corporation
5 *
6 * Wan ZongShun <mcuos.com@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation;version 2 of the License.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/device.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/string.h>
20#include <linux/clk.h>
21#include <linux/mutex.h>
22#include <linux/io.h>
23
24#include <mach/hardware.h>
25
26#define REG_MFSEL (W90X900_VA_GCR + 0xC)
27
28#define GPSELF (0x01 << 1)
29
30#define GPSELC (0x03 << 2)
31#define ENKPI (0x02 << 2)
32#define ENNAND (0x01 << 2)
33
34#define GPSELEI0 (0x01 << 26)
35#define GPSELEI1 (0x01 << 27)
36
37#define GPIOG0TO1 (0x03 << 14)
38#define GPIOG2TO3 (0x03 << 16)
39#define ENSPI (0x0a << 14)
40#define ENI2C0 (0x01 << 14)
41#define ENI2C1 (0x01 << 16)
42
43static DEFINE_MUTEX(mfp_mutex);
44
45void mfp_set_groupf(struct device *dev)
46{
47 unsigned long mfpen;
48 const char *dev_id;
49
50 BUG_ON(!dev);
51
52 mutex_lock(&mfp_mutex);
53
54 dev_id = dev_name(dev);
55
56 mfpen = __raw_readl(REG_MFSEL);
57
58 if (strcmp(dev_id, "nuc900-emc") == 0)
59 mfpen |= GPSELF;/*enable mac*/
60 else
61 mfpen &= ~GPSELF;/*GPIOF[9:0]*/
62
63 __raw_writel(mfpen, REG_MFSEL);
64
65 mutex_unlock(&mfp_mutex);
66}
67EXPORT_SYMBOL(mfp_set_groupf);
68
69void mfp_set_groupc(struct device *dev)
70{
71 unsigned long mfpen;
72 const char *dev_id;
73
74 BUG_ON(!dev);
75
76 mutex_lock(&mfp_mutex);
77
78 dev_id = dev_name(dev);
79
80 mfpen = __raw_readl(REG_MFSEL);
81
82 if (strcmp(dev_id, "nuc900-lcd") == 0)
83 mfpen |= GPSELC;/*enable lcd*/
84 else if (strcmp(dev_id, "nuc900-kpi") == 0) {
85 mfpen &= (~GPSELC);/*enable kpi*/
86 mfpen |= ENKPI;
87 } else if (strcmp(dev_id, "nuc900-nand") == 0) {
88 mfpen &= (~GPSELC);/*enable nand*/
89 mfpen |= ENNAND;
90 } else
91 mfpen &= (~GPSELC);/*GPIOC[14:0]*/
92
93 __raw_writel(mfpen, REG_MFSEL);
94
95 mutex_unlock(&mfp_mutex);
96}
97EXPORT_SYMBOL(mfp_set_groupc);
98
99void mfp_set_groupi(struct device *dev)
100{
101 unsigned long mfpen;
102 const char *dev_id;
103
104 BUG_ON(!dev);
105
106 mutex_lock(&mfp_mutex);
107
108 dev_id = dev_name(dev);
109
110 mfpen = __raw_readl(REG_MFSEL);
111
112 mfpen &= ~GPSELEI1;/*default gpio16*/
113
114 if (strcmp(dev_id, "nuc900-wdog") == 0)
115 mfpen |= GPSELEI1;/*enable wdog*/
116 else if (strcmp(dev_id, "nuc900-atapi") == 0)
117 mfpen |= GPSELEI0;/*enable atapi*/
118 else if (strcmp(dev_id, "nuc900-keypad") == 0)
119 mfpen &= ~GPSELEI0;/*enable keypad*/
120
121 __raw_writel(mfpen, REG_MFSEL);
122
123 mutex_unlock(&mfp_mutex);
124}
125EXPORT_SYMBOL(mfp_set_groupi);
126
127void mfp_set_groupg(struct device *dev)
128{
129 unsigned long mfpen;
130 const char *dev_id;
131
132 BUG_ON(!dev);
133
134 mutex_lock(&mfp_mutex);
135
136 dev_id = dev_name(dev);
137
138 mfpen = __raw_readl(REG_MFSEL);
139
140 if (strcmp(dev_id, "nuc900-spi") == 0) {
141 mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);
142 mfpen |= ENSPI;/*enable spi*/
143 } else if (strcmp(dev_id, "nuc900-i2c0") == 0) {
144 mfpen &= ~(GPIOG0TO1);
145 mfpen |= ENI2C0;/*enable i2c0*/
146 } else if (strcmp(dev_id, "nuc900-i2c1") == 0) {
147 mfpen &= ~(GPIOG2TO3);
148 mfpen |= ENI2C1;/*enable i2c1*/
149 } else {
150 mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
151 }
152
153 __raw_writel(mfpen, REG_MFSEL);
154
155 mutex_unlock(&mfp_mutex);
156}
157EXPORT_SYMBOL(mfp_set_groupg);
158
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c
new file mode 100644
index 000000000000..656f03b3b629
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.c
@@ -0,0 +1,60 @@
1/*
2 * linux/arch/arm/mach-w90x900/nuc910.c
3 *
4 * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
5 *
6 * Copyright (c) 2009 Nuvoton corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * NUC910 cpu support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation;version 2 of the License.
15 *
16 */
17
18#include <linux/platform_device.h>
19#include <asm/mach/map.h>
20#include <mach/hardware.h>
21#include "cpu.h"
22#include "clock.h"
23
24/* define specific CPU platform device */
25
26static struct platform_device *nuc910_dev[] __initdata = {
27 &nuc900_device_ts,
28 &nuc900_device_rtc,
29};
30
31/* define specific CPU platform io map */
32
33static struct map_desc nuc910evb_iodesc[] __initdata = {
34 IODESC_ENT(USBEHCIHOST),
35 IODESC_ENT(USBOHCIHOST),
36 IODESC_ENT(KPI),
37 IODESC_ENT(USBDEV),
38 IODESC_ENT(ADC),
39};
40
41/*Init NUC910 evb io*/
42
43void __init nuc910_map_io(void)
44{
45 nuc900_map_io(nuc910evb_iodesc, ARRAY_SIZE(nuc910evb_iodesc));
46}
47
48/*Init NUC910 clock*/
49
50void __init nuc910_init_clocks(void)
51{
52 nuc900_init_clocks();
53}
54
55/*Init NUC910 board info*/
56
57void __init nuc910_board_init(void)
58{
59 nuc900_board_init(nuc910_dev, ARRAY_SIZE(nuc910_dev));
60}
diff --git a/arch/arm/mach-w90x900/nuc910.h b/arch/arm/mach-w90x900/nuc910.h
new file mode 100644
index 000000000000..83e9ba5fc26c
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-w90x900/nuc910.h
3 *
4 * Copyright (c) 2008 Nuvoton corporation
5 *
6 * Header file for NUC900 CPU support
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16struct map_desc;
17struct sys_timer;
18
19/* core initialisation functions */
20
21extern void nuc900_init_irq(void);
22extern struct sys_timer nuc900_timer;
23
24/* extern file from nuc910.c */
25
26extern void nuc910_board_init(void);
27extern void nuc910_init_clocks(void);
28extern void nuc910_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c
new file mode 100644
index 000000000000..149508116d18
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.c
@@ -0,0 +1,54 @@
1/*
2 * linux/arch/arm/mach-w90x900/nuc950.c
3 *
4 * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
5 *
6 * Copyright (c) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * NUC950 cpu support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation;version 2 of the License.
15 *
16 */
17
18#include <linux/platform_device.h>
19#include <asm/mach/map.h>
20#include <mach/hardware.h>
21#include "cpu.h"
22
23/* define specific CPU platform device */
24
25static struct platform_device *nuc950_dev[] __initdata = {
26 &nuc900_device_kpi,
27 &nuc900_device_fmi,
28};
29
30/* define specific CPU platform io map */
31
32static struct map_desc nuc950evb_iodesc[] __initdata = {
33};
34
35/*Init NUC950 evb io*/
36
37void __init nuc950_map_io(void)
38{
39 nuc900_map_io(nuc950evb_iodesc, ARRAY_SIZE(nuc950evb_iodesc));
40}
41
42/*Init NUC950 clock*/
43
44void __init nuc950_init_clocks(void)
45{
46 nuc900_init_clocks();
47}
48
49/*Init NUC950 board info*/
50
51void __init nuc950_board_init(void)
52{
53 nuc900_board_init(nuc950_dev, ARRAY_SIZE(nuc950_dev));
54}
diff --git a/arch/arm/mach-w90x900/nuc950.h b/arch/arm/mach-w90x900/nuc950.h
new file mode 100644
index 000000000000..98a1148bc5ae
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-w90x900/nuc950.h
3 *
4 * Copyright (c) 2008 Nuvoton corporation
5 *
6 * Header file for NUC900 CPU support
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16struct map_desc;
17struct sys_timer;
18
19/* core initialisation functions */
20
21extern void nuc900_init_irq(void);
22extern struct sys_timer nuc900_timer;
23
24/* extern file from nuc950.c */
25
26extern void nuc950_board_init(void);
27extern void nuc950_init_clocks(void);
28extern void nuc950_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc960.c b/arch/arm/mach-w90x900/nuc960.c
new file mode 100644
index 000000000000..8851a3a27ce2
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.c
@@ -0,0 +1,54 @@
1/*
2 * linux/arch/arm/mach-w90x900/nuc960.c
3 *
4 * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
5 *
6 * Copyright (c) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * NUC960 cpu support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation;version 2 of the License.
15 *
16 */
17
18#include <linux/platform_device.h>
19#include <asm/mach/map.h>
20#include <mach/hardware.h>
21#include "cpu.h"
22
23/* define specific CPU platform device */
24
25static struct platform_device *nuc960_dev[] __initdata = {
26 &nuc900_device_kpi,
27 &nuc900_device_fmi,
28};
29
30/* define specific CPU platform io map */
31
32static struct map_desc nuc960evb_iodesc[] __initdata = {
33};
34
35/*Init NUC960 evb io*/
36
37void __init nuc960_map_io(void)
38{
39 nuc900_map_io(nuc960evb_iodesc, ARRAY_SIZE(nuc960evb_iodesc));
40}
41
42/*Init NUC960 clock*/
43
44void __init nuc960_init_clocks(void)
45{
46 nuc900_init_clocks();
47}
48
49/*Init NUC960 board info*/
50
51void __init nuc960_board_init(void)
52{
53 nuc900_board_init(nuc960_dev, ARRAY_SIZE(nuc960_dev));
54}
diff --git a/arch/arm/mach-w90x900/nuc960.h b/arch/arm/mach-w90x900/nuc960.h
new file mode 100644
index 000000000000..f0c07cbe3a82
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-w90x900/nuc960.h
3 *
4 * Copyright (c) 2008 Nuvoton corporation
5 *
6 * Header file for NUC900 CPU support
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16struct map_desc;
17struct sys_timer;
18
19/* core initialisation functions */
20
21extern void nuc900_init_irq(void);
22extern struct sys_timer nuc900_timer;
23
24/* extern file from nuc960.c */
25
26extern void nuc960_board_init(void);
27extern void nuc960_init_clocks(void);
28extern void nuc960_map_io(void);
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index bcc838f6b393..4128af870b41 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks 4 * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks
5 * 5 *
6 * Copyright (c) 2008 Nuvoton technology corporation 6 * Copyright (c) 2009 Nuvoton technology corporation
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Wan ZongShun <mcuos.com@gmail.com> 9 * Wan ZongShun <mcuos.com@gmail.com>
@@ -23,6 +23,8 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/leds.h> 25#include <linux/leds.h>
26#include <linux/clocksource.h>
27#include <linux/clockchips.h>
26 28
27#include <asm/mach-types.h> 29#include <asm/mach-types.h>
28#include <asm/mach/irq.h> 30#include <asm/mach/irq.h>
@@ -31,49 +33,150 @@
31#include <mach/map.h> 33#include <mach/map.h>
32#include <mach/regs-timer.h> 34#include <mach/regs-timer.h>
33 35
34static unsigned long w90x900_gettimeoffset(void) 36#define RESETINT 0x1f
37#define PERIOD (0x01 << 27)
38#define ONESHOT (0x00 << 27)
39#define COUNTEN (0x01 << 30)
40#define INTEN (0x01 << 29)
41
42#define TICKS_PER_SEC 100
43#define PRESCALE 0x63 /* Divider = prescale + 1 */
44
45unsigned int timer0_load;
46
47static void nuc900_clockevent_setmode(enum clock_event_mode mode,
48 struct clock_event_device *clk)
35{ 49{
50 unsigned int val;
51
52 val = __raw_readl(REG_TCSR0);
53 val &= ~(0x03 << 27);
54
55 switch (mode) {
56 case CLOCK_EVT_MODE_PERIODIC:
57 __raw_writel(timer0_load, REG_TICR0);
58 val |= (PERIOD | COUNTEN | INTEN | PRESCALE);
59 break;
60
61 case CLOCK_EVT_MODE_ONESHOT:
62 val |= (ONESHOT | COUNTEN | INTEN | PRESCALE);
63 break;
64
65 case CLOCK_EVT_MODE_UNUSED:
66 case CLOCK_EVT_MODE_SHUTDOWN:
67 case CLOCK_EVT_MODE_RESUME:
68 break;
69 }
70
71 __raw_writel(val, REG_TCSR0);
72}
73
74static int nuc900_clockevent_setnextevent(unsigned long evt,
75 struct clock_event_device *clk)
76{
77 unsigned int val;
78
79 __raw_writel(evt, REG_TICR0);
80
81 val = __raw_readl(REG_TCSR0);
82 val |= (COUNTEN | INTEN | PRESCALE);
83 __raw_writel(val, REG_TCSR0);
84
36 return 0; 85 return 0;
37} 86}
38 87
88static struct clock_event_device nuc900_clockevent_device = {
89 .name = "nuc900-timer0",
90 .shift = 32,
91 .features = CLOCK_EVT_MODE_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
92 .set_mode = nuc900_clockevent_setmode,
93 .set_next_event = nuc900_clockevent_setnextevent,
94 .rating = 300,
95};
96
39/*IRQ handler for the timer*/ 97/*IRQ handler for the timer*/
40 98
41static irqreturn_t 99static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id)
42w90x900_timer_interrupt(int irq, void *dev_id)
43{ 100{
44 timer_tick(); 101 struct clock_event_device *evt = &nuc900_clockevent_device;
102
45 __raw_writel(0x01, REG_TISR); /* clear TIF0 */ 103 __raw_writel(0x01, REG_TISR); /* clear TIF0 */
104
105 evt->event_handler(evt);
46 return IRQ_HANDLED; 106 return IRQ_HANDLED;
47} 107}
48 108
49static struct irqaction w90x900_timer_irq = { 109static struct irqaction nuc900_timer0_irq = {
50 .name = "w90x900 Timer Tick", 110 .name = "nuc900-timer0",
51 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 111 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
52 .handler = w90x900_timer_interrupt, 112 .handler = nuc900_timer0_interrupt,
53}; 113};
54 114
55/*Set up timer reg.*/ 115static void __init nuc900_clockevents_init(unsigned int rate)
116{
117 nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC,
118 nuc900_clockevent_device.shift);
119 nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff,
120 &nuc900_clockevent_device);
121 nuc900_clockevent_device.min_delta_ns = clockevent_delta2ns(0xf,
122 &nuc900_clockevent_device);
123 nuc900_clockevent_device.cpumask = cpumask_of(0);
56 124
57static void w90x900_timer_setup(void) 125 clockevents_register_device(&nuc900_clockevent_device);
126}
127
128static cycle_t nuc900_get_cycles(struct clocksource *cs)
58{ 129{
59 __raw_writel(0, REG_TCSR0); 130 return ~__raw_readl(REG_TDR1);
60 __raw_writel(0, REG_TCSR1);
61 __raw_writel(0, REG_TCSR2);
62 __raw_writel(0, REG_TCSR3);
63 __raw_writel(0, REG_TCSR4);
64 __raw_writel(0x1F, REG_TISR);
65 __raw_writel(15000000/(100 * 100), REG_TICR0);
66 __raw_writel(0x68000063, REG_TCSR0);
67} 131}
68 132
69static void __init w90x900_timer_init(void) 133static struct clocksource clocksource_nuc900 = {
134 .name = "nuc900-timer1",
135 .rating = 200,
136 .read = nuc900_get_cycles,
137 .mask = CLOCKSOURCE_MASK(32),
138 .shift = 20,
139 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
140};
141
142static void __init nuc900_clocksource_init(unsigned int rate)
70{ 143{
71 w90x900_timer_setup(); 144 unsigned int val;
72 setup_irq(IRQ_TIMER0, &w90x900_timer_irq); 145
146 __raw_writel(0xffffffff, REG_TICR1);
147
148 val = __raw_readl(REG_TCSR1);
149 val |= (COUNTEN | PERIOD);
150 __raw_writel(val, REG_TCSR1);
151
152 clocksource_nuc900.mult =
153 clocksource_khz2mult((rate / 1000), clocksource_nuc900.shift);
154 clocksource_register(&clocksource_nuc900);
155}
156
157static void __init nuc900_timer_init(void)
158{
159 struct clk *ck_ext = clk_get(NULL, "ext");
160 unsigned int rate;
161
162 BUG_ON(IS_ERR(ck_ext));
163
164 rate = clk_get_rate(ck_ext);
165 clk_put(ck_ext);
166 rate = rate / (PRESCALE + 0x01);
167
168 /* set a known state */
169 __raw_writel(0x00, REG_TCSR0);
170 __raw_writel(0x00, REG_TCSR1);
171 __raw_writel(RESETINT, REG_TISR);
172 timer0_load = (rate / TICKS_PER_SEC);
173
174 setup_irq(IRQ_TIMER0, &nuc900_timer0_irq);
175
176 nuc900_clocksource_init(rate);
177 nuc900_clockevents_init(rate);
73} 178}
74 179
75struct sys_timer w90x900_timer = { 180struct sys_timer nuc900_timer = {
76 .init = w90x900_timer_init, 181 .init = nuc900_timer_init,
77 .offset = w90x900_gettimeoffset,
78 .resume = w90x900_timer_setup
79}; 182};
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c
deleted file mode 100644
index 1c97e4930b7a..000000000000
--- a/arch/arm/mach-w90x900/w90p910.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 * linux/arch/arm/mach-w90x900/w90p910.c
3 *
4 * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
5 *
6 * Copyright (c) 2008 Nuvoton technology corporation.
7 *
8 * Wan ZongShun <mcuos.com@gmail.com>
9 *
10 * W90P910 cpu support
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation;version 2 of the License.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/interrupt.h>
21#include <linux/list.h>
22#include <linux/timer.h>
23#include <linux/init.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26#include <linux/serial_8250.h>
27
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/mach/irq.h>
31#include <asm/irq.h>
32
33#include <mach/hardware.h>
34#include <mach/regs-serial.h>
35
36#include "cpu.h"
37#include "clock.h"
38
39/* Initial IO mappings */
40
41static struct map_desc w90p910_iodesc[] __initdata = {
42 IODESC_ENT(IRQ),
43 IODESC_ENT(GCR),
44 IODESC_ENT(UART),
45 IODESC_ENT(TIMER),
46 IODESC_ENT(EBI),
47 IODESC_ENT(USBEHCIHOST),
48 IODESC_ENT(USBOHCIHOST),
49 IODESC_ENT(ADC),
50 IODESC_ENT(RTC),
51 IODESC_ENT(KPI),
52 IODESC_ENT(USBDEV),
53 /*IODESC_ENT(LCD),*/
54};
55
56/* Initial clock declarations. */
57static DEFINE_CLK(lcd, 0);
58static DEFINE_CLK(audio, 1);
59static DEFINE_CLK(fmi, 4);
60static DEFINE_CLK(dmac, 5);
61static DEFINE_CLK(atapi, 6);
62static DEFINE_CLK(emc, 7);
63static DEFINE_CLK(usbd, 8);
64static DEFINE_CLK(usbh, 9);
65static DEFINE_CLK(g2d, 10);;
66static DEFINE_CLK(pwm, 18);
67static DEFINE_CLK(ps2, 24);
68static DEFINE_CLK(kpi, 25);
69static DEFINE_CLK(wdt, 26);
70static DEFINE_CLK(gdma, 27);
71static DEFINE_CLK(adc, 28);
72static DEFINE_CLK(usi, 29);
73
74static struct clk_lookup w90p910_clkregs[] = {
75 DEF_CLKLOOK(&clk_lcd, "w90p910-lcd", NULL),
76 DEF_CLKLOOK(&clk_audio, "w90p910-audio", NULL),
77 DEF_CLKLOOK(&clk_fmi, "w90p910-fmi", NULL),
78 DEF_CLKLOOK(&clk_dmac, "w90p910-dmac", NULL),
79 DEF_CLKLOOK(&clk_atapi, "w90p910-atapi", NULL),
80 DEF_CLKLOOK(&clk_emc, "w90p910-emc", NULL),
81 DEF_CLKLOOK(&clk_usbd, "w90p910-usbd", NULL),
82 DEF_CLKLOOK(&clk_usbh, "w90p910-usbh", NULL),
83 DEF_CLKLOOK(&clk_g2d, "w90p910-g2d", NULL),
84 DEF_CLKLOOK(&clk_pwm, "w90p910-pwm", NULL),
85 DEF_CLKLOOK(&clk_ps2, "w90p910-ps2", NULL),
86 DEF_CLKLOOK(&clk_kpi, "w90p910-kpi", NULL),
87 DEF_CLKLOOK(&clk_wdt, "w90p910-wdt", NULL),
88 DEF_CLKLOOK(&clk_gdma, "w90p910-gdma", NULL),
89 DEF_CLKLOOK(&clk_adc, "w90p910-adc", NULL),
90 DEF_CLKLOOK(&clk_usi, "w90p910-usi", NULL),
91};
92
93/* Initial serial platform data */
94
95struct plat_serial8250_port w90p910_uart_data[] = {
96 W90X900_8250PORT(UART0),
97};
98
99struct platform_device w90p910_serial_device = {
100 .name = "serial8250",
101 .id = PLAT8250_DEV_PLATFORM,
102 .dev = {
103 .platform_data = w90p910_uart_data,
104 },
105};
106
107/*Init W90P910 evb io*/
108
109void __init w90p910_map_io(struct map_desc *mach_desc, int mach_size)
110{
111 unsigned long idcode = 0x0;
112
113 iotable_init(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
114
115 idcode = __raw_readl(W90X900PDID);
116 if (idcode != W90P910_CPUID)
117 printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode);
118}
119
120/*Init W90P910 clock*/
121
122void __init w90p910_init_clocks(void)
123{
124 clks_register(w90p910_clkregs, ARRAY_SIZE(w90p910_clkregs));
125}
126
127static int __init w90p910_init_cpu(void)
128{
129 return 0;
130}
131
132static int __init w90x900_arch_init(void)
133{
134 return w90p910_init_cpu();
135}
136arch_initcall(w90x900_arch_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 83c025e72ceb..5fe595aeba69 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -758,7 +758,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
758config CACHE_L2X0 758config CACHE_L2X0
759 bool "Enable the L2x0 outer cache controller" 759 bool "Enable the L2x0 outer cache controller"
760 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ 760 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
761 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX 761 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK
762 default y 762 default y
763 select OUTER_CACHE 763 select OUTER_CACHE
764 help 764 help
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 03cd27d917b9..b270d6228fe2 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -159,7 +159,9 @@ union offset_union {
159 159
160#define __get8_unaligned_check(ins,val,addr,err) \ 160#define __get8_unaligned_check(ins,val,addr,err) \
161 __asm__( \ 161 __asm__( \
162 "1: "ins" %1, [%2], #1\n" \ 162 ARM( "1: "ins" %1, [%2], #1\n" ) \
163 THUMB( "1: "ins" %1, [%2]\n" ) \
164 THUMB( " add %2, %2, #1\n" ) \
163 "2:\n" \ 165 "2:\n" \
164 " .section .fixup,\"ax\"\n" \ 166 " .section .fixup,\"ax\"\n" \
165 " .align 2\n" \ 167 " .align 2\n" \
@@ -215,7 +217,9 @@ union offset_union {
215 do { \ 217 do { \
216 unsigned int err = 0, v = val, a = addr; \ 218 unsigned int err = 0, v = val, a = addr; \
217 __asm__( FIRST_BYTE_16 \ 219 __asm__( FIRST_BYTE_16 \
218 "1: "ins" %1, [%2], #1\n" \ 220 ARM( "1: "ins" %1, [%2], #1\n" ) \
221 THUMB( "1: "ins" %1, [%2]\n" ) \
222 THUMB( " add %2, %2, #1\n" ) \
219 " mov %1, %1, "NEXT_BYTE"\n" \ 223 " mov %1, %1, "NEXT_BYTE"\n" \
220 "2: "ins" %1, [%2]\n" \ 224 "2: "ins" %1, [%2]\n" \
221 "3:\n" \ 225 "3:\n" \
@@ -245,11 +249,17 @@ union offset_union {
245 do { \ 249 do { \
246 unsigned int err = 0, v = val, a = addr; \ 250 unsigned int err = 0, v = val, a = addr; \
247 __asm__( FIRST_BYTE_32 \ 251 __asm__( FIRST_BYTE_32 \
248 "1: "ins" %1, [%2], #1\n" \ 252 ARM( "1: "ins" %1, [%2], #1\n" ) \
253 THUMB( "1: "ins" %1, [%2]\n" ) \
254 THUMB( " add %2, %2, #1\n" ) \
249 " mov %1, %1, "NEXT_BYTE"\n" \ 255 " mov %1, %1, "NEXT_BYTE"\n" \
250 "2: "ins" %1, [%2], #1\n" \ 256 ARM( "2: "ins" %1, [%2], #1\n" ) \
257 THUMB( "2: "ins" %1, [%2]\n" ) \
258 THUMB( " add %2, %2, #1\n" ) \
251 " mov %1, %1, "NEXT_BYTE"\n" \ 259 " mov %1, %1, "NEXT_BYTE"\n" \
252 "3: "ins" %1, [%2], #1\n" \ 260 ARM( "3: "ins" %1, [%2], #1\n" ) \
261 THUMB( "3: "ins" %1, [%2]\n" ) \
262 THUMB( " add %2, %2, #1\n" ) \
253 " mov %1, %1, "NEXT_BYTE"\n" \ 263 " mov %1, %1, "NEXT_BYTE"\n" \
254 "4: "ins" %1, [%2]\n" \ 264 "4: "ins" %1, [%2]\n" \
255 "5:\n" \ 265 "5:\n" \
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index be93ff02a98d..bda0ec31a4e2 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -21,7 +21,7 @@
21 * 21 *
22 * Flush the whole D-cache. 22 * Flush the whole D-cache.
23 * 23 *
24 * Corrupted registers: r0-r5, r7, r9-r11 24 * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
25 * 25 *
26 * - mm - mm_struct describing address space 26 * - mm - mm_struct describing address space
27 */ 27 */
@@ -51,8 +51,12 @@ loop1:
51loop2: 51loop2:
52 mov r9, r4 @ create working copy of max way size 52 mov r9, r4 @ create working copy of max way size
53loop3: 53loop3:
54 orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 54 ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
55 orr r11, r11, r7, lsl r2 @ factor index number into r11 55 THUMB( lsl r6, r9, r5 )
56 THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
57 ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
58 THUMB( lsl r6, r7, r2 )
59 THUMB( orr r11, r11, r6 ) @ factor index number into r11
56 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way 60 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
57 subs r9, r9, #1 @ decrement the way 61 subs r9, r9, #1 @ decrement the way
58 bge loop3 62 bge loop3
@@ -82,11 +86,13 @@ ENDPROC(v7_flush_dcache_all)
82 * 86 *
83 */ 87 */
84ENTRY(v7_flush_kern_cache_all) 88ENTRY(v7_flush_kern_cache_all)
85 stmfd sp!, {r4-r5, r7, r9-r11, lr} 89 ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
90 THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
86 bl v7_flush_dcache_all 91 bl v7_flush_dcache_all
87 mov r0, #0 92 mov r0, #0
88 mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate 93 mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
89 ldmfd sp!, {r4-r5, r7, r9-r11, lr} 94 ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
95 THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
90 mov pc, lr 96 mov pc, lr
91ENDPROC(v7_flush_kern_cache_all) 97ENDPROC(v7_flush_kern_cache_all)
92 98
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 510c179b0ac8..b30925fcbcdc 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -36,7 +36,34 @@
36#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) 36#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
37#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) 37#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
38 38
39static u64 get_coherent_dma_mask(struct device *dev)
40{
41 u64 mask = ISA_DMA_THRESHOLD;
42
43 if (dev) {
44 mask = dev->coherent_dma_mask;
45
46 /*
47 * Sanity check the DMA mask - it must be non-zero, and
48 * must be able to be satisfied by a DMA allocation.
49 */
50 if (mask == 0) {
51 dev_warn(dev, "coherent DMA mask is unset\n");
52 return 0;
53 }
54
55 if ((~mask) & ISA_DMA_THRESHOLD) {
56 dev_warn(dev, "coherent DMA mask %#llx is smaller "
57 "than system GFP_DMA mask %#llx\n",
58 mask, (unsigned long long)ISA_DMA_THRESHOLD);
59 return 0;
60 }
61 }
39 62
63 return mask;
64}
65
66#ifdef CONFIG_MMU
40/* 67/*
41 * These are the page tables (2MB each) covering uncached, DMA consistent allocations 68 * These are the page tables (2MB each) covering uncached, DMA consistent allocations
42 */ 69 */
@@ -152,7 +179,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
152 struct page *page; 179 struct page *page;
153 struct arm_vm_region *c; 180 struct arm_vm_region *c;
154 unsigned long order; 181 unsigned long order;
155 u64 mask = ISA_DMA_THRESHOLD, limit; 182 u64 mask = get_coherent_dma_mask(dev);
183 u64 limit;
156 184
157 if (!consistent_pte[0]) { 185 if (!consistent_pte[0]) {
158 printk(KERN_ERR "%s: not initialised\n", __func__); 186 printk(KERN_ERR "%s: not initialised\n", __func__);
@@ -160,25 +188,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
160 return NULL; 188 return NULL;
161 } 189 }
162 190
163 if (dev) { 191 if (!mask)
164 mask = dev->coherent_dma_mask; 192 goto no_page;
165
166 /*
167 * Sanity check the DMA mask - it must be non-zero, and
168 * must be able to be satisfied by a DMA allocation.
169 */
170 if (mask == 0) {
171 dev_warn(dev, "coherent DMA mask is unset\n");
172 goto no_page;
173 }
174
175 if ((~mask) & ISA_DMA_THRESHOLD) {
176 dev_warn(dev, "coherent DMA mask %#llx is smaller "
177 "than system GFP_DMA mask %#llx\n",
178 mask, (unsigned long long)ISA_DMA_THRESHOLD);
179 goto no_page;
180 }
181 }
182 193
183 /* 194 /*
184 * Sanity check the allocation size. 195 * Sanity check the allocation size.
@@ -267,6 +278,31 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
267 *handle = ~0; 278 *handle = ~0;
268 return NULL; 279 return NULL;
269} 280}
281#else /* !CONFIG_MMU */
282static void *
283__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
284 pgprot_t prot)
285{
286 void *virt;
287 u64 mask = get_coherent_dma_mask(dev);
288
289 if (!mask)
290 goto error;
291
292 if (mask != 0xffffffff)
293 gfp |= GFP_DMA;
294 virt = kmalloc(size, gfp);
295 if (!virt)
296 goto error;
297
298 *handle = virt_to_dma(dev, virt);
299 return virt;
300
301error:
302 *handle = ~0;
303 return NULL;
304}
305#endif /* CONFIG_MMU */
270 306
271/* 307/*
272 * Allocate DMA-coherent memory space and return both the kernel remapped 308 * Allocate DMA-coherent memory space and return both the kernel remapped
@@ -311,9 +347,10 @@ EXPORT_SYMBOL(dma_alloc_writecombine);
311static int dma_mmap(struct device *dev, struct vm_area_struct *vma, 347static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
312 void *cpu_addr, dma_addr_t dma_addr, size_t size) 348 void *cpu_addr, dma_addr_t dma_addr, size_t size)
313{ 349{
350 int ret = -ENXIO;
351#ifdef CONFIG_MMU
314 unsigned long flags, user_size, kern_size; 352 unsigned long flags, user_size, kern_size;
315 struct arm_vm_region *c; 353 struct arm_vm_region *c;
316 int ret = -ENXIO;
317 354
318 user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 355 user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
319 356
@@ -334,6 +371,7 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
334 vma->vm_page_prot); 371 vma->vm_page_prot);
335 } 372 }
336 } 373 }
374#endif /* CONFIG_MMU */
337 375
338 return ret; 376 return ret;
339} 377}
@@ -358,6 +396,7 @@ EXPORT_SYMBOL(dma_mmap_writecombine);
358 * free a page as defined by the above mapping. 396 * free a page as defined by the above mapping.
359 * Must not be called with IRQs disabled. 397 * Must not be called with IRQs disabled.
360 */ 398 */
399#ifdef CONFIG_MMU
361void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) 400void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
362{ 401{
363 struct arm_vm_region *c; 402 struct arm_vm_region *c;
@@ -444,6 +483,14 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
444 __func__, cpu_addr); 483 __func__, cpu_addr);
445 dump_stack(); 484 dump_stack();
446} 485}
486#else /* !CONFIG_MMU */
487void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
488{
489 if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
490 return;
491 kfree(cpu_addr);
492}
493#endif /* CONFIG_MMU */
447EXPORT_SYMBOL(dma_free_coherent); 494EXPORT_SYMBOL(dma_free_coherent);
448 495
449/* 496/*
@@ -451,10 +498,12 @@ EXPORT_SYMBOL(dma_free_coherent);
451 */ 498 */
452static int __init consistent_init(void) 499static int __init consistent_init(void)
453{ 500{
501 int ret = 0;
502#ifdef CONFIG_MMU
454 pgd_t *pgd; 503 pgd_t *pgd;
455 pmd_t *pmd; 504 pmd_t *pmd;
456 pte_t *pte; 505 pte_t *pte;
457 int ret = 0, i = 0; 506 int i = 0;
458 u32 base = CONSISTENT_BASE; 507 u32 base = CONSISTENT_BASE;
459 508
460 do { 509 do {
@@ -477,6 +526,7 @@ static int __init consistent_init(void)
477 consistent_pte[i++] = pte; 526 consistent_pte[i++] = pte;
478 base += (1 << PGDIR_SHIFT); 527 base += (1 << PGDIR_SHIFT);
479 } while (base < CONSISTENT_END); 528 } while (base < CONSISTENT_END);
529#endif /* !CONFIG_MMU */
480 530
481 return ret; 531 return ret;
482} 532}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 6fdcbb709827..cc8829d7e116 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -16,6 +16,8 @@
16#include <linux/kprobes.h> 16#include <linux/kprobes.h>
17#include <linux/uaccess.h> 17#include <linux/uaccess.h>
18#include <linux/page-flags.h> 18#include <linux/page-flags.h>
19#include <linux/sched.h>
20#include <linux/highmem.h>
19 21
20#include <asm/system.h> 22#include <asm/system.h>
21#include <asm/pgtable.h> 23#include <asm/pgtable.h>
@@ -23,6 +25,7 @@
23 25
24#include "fault.h" 26#include "fault.h"
25 27
28#ifdef CONFIG_MMU
26 29
27#ifdef CONFIG_KPROBES 30#ifdef CONFIG_KPROBES
28static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) 31static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
@@ -97,6 +100,10 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
97 100
98 printk("\n"); 101 printk("\n");
99} 102}
103#else /* CONFIG_MMU */
104void show_pte(struct mm_struct *mm, unsigned long addr)
105{ }
106#endif /* CONFIG_MMU */
100 107
101/* 108/*
102 * Oops. The kernel tried to access some page that wasn't present. 109 * Oops. The kernel tried to access some page that wasn't present.
@@ -171,6 +178,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
171 __do_kernel_fault(mm, addr, fsr, regs); 178 __do_kernel_fault(mm, addr, fsr, regs);
172} 179}
173 180
181#ifdef CONFIG_MMU
174#define VM_FAULT_BADMAP 0x010000 182#define VM_FAULT_BADMAP 0x010000
175#define VM_FAULT_BADACCESS 0x020000 183#define VM_FAULT_BADACCESS 0x020000
176 184
@@ -322,6 +330,13 @@ no_context:
322 __do_kernel_fault(mm, addr, fsr, regs); 330 __do_kernel_fault(mm, addr, fsr, regs);
323 return 0; 331 return 0;
324} 332}
333#else /* CONFIG_MMU */
334static int
335do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
336{
337 return 0;
338}
339#endif /* CONFIG_MMU */
325 340
326/* 341/*
327 * First Level Translation Fault Handler 342 * First Level Translation Fault Handler
@@ -340,6 +355,7 @@ no_context:
340 * interrupt or a critical region, and should only copy the information 355 * interrupt or a critical region, and should only copy the information
341 * from the master page table, nothing more. 356 * from the master page table, nothing more.
342 */ 357 */
358#ifdef CONFIG_MMU
343static int __kprobes 359static int __kprobes
344do_translation_fault(unsigned long addr, unsigned int fsr, 360do_translation_fault(unsigned long addr, unsigned int fsr,
345 struct pt_regs *regs) 361 struct pt_regs *regs)
@@ -378,6 +394,14 @@ bad_area:
378 do_bad_area(addr, fsr, regs); 394 do_bad_area(addr, fsr, regs);
379 return 0; 395 return 0;
380} 396}
397#else /* CONFIG_MMU */
398static int
399do_translation_fault(unsigned long addr, unsigned int fsr,
400 struct pt_regs *regs)
401{
402 return 0;
403}
404#endif /* CONFIG_MMU */
381 405
382/* 406/*
383 * Some section permission faults need to be handled gracefully. 407 * Some section permission faults need to be handled gracefully.
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c07222eb5ce0..575f3ad722e7 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -144,7 +144,14 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
144 * page. This ensures that data in the physical page is mutually 144 * page. This ensures that data in the physical page is mutually
145 * coherent with the kernels mapping. 145 * coherent with the kernels mapping.
146 */ 146 */
147 __cpuc_flush_dcache_page(page_address(page)); 147#ifdef CONFIG_HIGHMEM
148 /*
149 * kmap_atomic() doesn't set the page virtual address, and
150 * kunmap_atomic() takes care of cache flushing already.
151 */
152 if (page_address(page))
153#endif
154 __cpuc_flush_dcache_page(page_address(page));
148 155
149 /* 156 /*
150 * If this is a page cache page, and we have an aliasing VIPT cache, 157 * If this is a page cache page, and we have an aliasing VIPT cache,
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index a34954d9df7d..73cae57fa707 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -40,11 +40,16 @@ void *kmap_atomic(struct page *page, enum km_type type)
40{ 40{
41 unsigned int idx; 41 unsigned int idx;
42 unsigned long vaddr; 42 unsigned long vaddr;
43 void *kmap;
43 44
44 pagefault_disable(); 45 pagefault_disable();
45 if (!PageHighMem(page)) 46 if (!PageHighMem(page))
46 return page_address(page); 47 return page_address(page);
47 48
49 kmap = kmap_high_get(page);
50 if (kmap)
51 return kmap;
52
48 idx = type + KM_TYPE_NR * smp_processor_id(); 53 idx = type + KM_TYPE_NR * smp_processor_id();
49 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 54 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
50#ifdef CONFIG_DEBUG_HIGHMEM 55#ifdef CONFIG_DEBUG_HIGHMEM
@@ -80,6 +85,9 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
80#else 85#else
81 (void) idx; /* to kill a warning */ 86 (void) idx; /* to kill a warning */
82#endif 87#endif
88 } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
89 /* this address was obtained through kmap_high_get() */
90 kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
83 } 91 }
84 pagefault_enable(); 92 pagefault_enable();
85} 93}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 3a7279c1ce5e..ea36186f32c3 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,6 +15,7 @@
15#include <linux/mman.h> 15#include <linux/mman.h>
16#include <linux/nodemask.h> 16#include <linux/nodemask.h>
17#include <linux/initrd.h> 17#include <linux/initrd.h>
18#include <linux/sort.h>
18#include <linux/highmem.h> 19#include <linux/highmem.h>
19 20
20#include <asm/mach-types.h> 21#include <asm/mach-types.h>
@@ -349,12 +350,43 @@ static void __init bootmem_free_node(int node, struct meminfo *mi)
349 free_area_init_node(node, zone_size, min, zhole_size); 350 free_area_init_node(node, zone_size, min, zhole_size);
350} 351}
351 352
353#ifndef CONFIG_SPARSEMEM
354int pfn_valid(unsigned long pfn)
355{
356 struct meminfo *mi = &meminfo;
357 unsigned int left = 0, right = mi->nr_banks;
358
359 do {
360 unsigned int mid = (right + left) / 2;
361 struct membank *bank = &mi->bank[mid];
362
363 if (pfn < bank_pfn_start(bank))
364 right = mid;
365 else if (pfn >= bank_pfn_end(bank))
366 left = mid + 1;
367 else
368 return 1;
369 } while (left < right);
370 return 0;
371}
372EXPORT_SYMBOL(pfn_valid);
373#endif
374
375static int __init meminfo_cmp(const void *_a, const void *_b)
376{
377 const struct membank *a = _a, *b = _b;
378 long cmp = bank_pfn_start(a) - bank_pfn_start(b);
379 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
380}
381
352void __init bootmem_init(void) 382void __init bootmem_init(void)
353{ 383{
354 struct meminfo *mi = &meminfo; 384 struct meminfo *mi = &meminfo;
355 unsigned long min, max_low, max_high; 385 unsigned long min, max_low, max_high;
356 int node, initrd_node; 386 int node, initrd_node;
357 387
388 sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
389
358 /* 390 /*
359 * Locate which node contains the ramdisk image, if any. 391 * Locate which node contains the ramdisk image, if any.
360 */ 392 */
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index ad7bacc693b2..900811cc9130 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -12,6 +12,7 @@
12#include <asm/cacheflush.h> 12#include <asm/cacheflush.h>
13#include <asm/sections.h> 13#include <asm/sections.h>
14#include <asm/page.h> 14#include <asm/page.h>
15#include <asm/setup.h>
15#include <asm/mach/arch.h> 16#include <asm/mach/arch.h>
16 17
17#include "mm.h" 18#include "mm.h"
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 54b1f721dec8..7d63beaf9745 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -77,19 +77,15 @@
77 * Sanity check the PTE configuration for the code below - which makes 77 * Sanity check the PTE configuration for the code below - which makes
78 * certain assumptions about how these bits are layed out. 78 * certain assumptions about how these bits are layed out.
79 */ 79 */
80#ifdef CONFIG_MMU
80#if L_PTE_SHARED != PTE_EXT_SHARED 81#if L_PTE_SHARED != PTE_EXT_SHARED
81#error PTE shared bit mismatch 82#error PTE shared bit mismatch
82#endif 83#endif
83#if L_PTE_BUFFERABLE != PTE_BUFFERABLE
84#error PTE bufferable bit mismatch
85#endif
86#if L_PTE_CACHEABLE != PTE_CACHEABLE
87#error PTE cacheable bit mismatch
88#endif
89#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ 84#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
90 L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED 85 L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
91#error Invalid Linux PTE bit settings 86#error Invalid Linux PTE bit settings
92#endif 87#endif
88#endif /* CONFIG_MMU */
93 89
94/* 90/*
95 * The ARMv6 and ARMv7 set_pte_ext translation function. 91 * The ARMv6 and ARMv7 set_pte_ext translation function.
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 180a08d03a03..f3fa1c32fe92 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -127,7 +127,9 @@ ENDPROC(cpu_v7_switch_mm)
127 */ 127 */
128ENTRY(cpu_v7_set_pte_ext) 128ENTRY(cpu_v7_set_pte_ext)
129#ifdef CONFIG_MMU 129#ifdef CONFIG_MMU
130 str r1, [r0], #-2048 @ linux version 130 ARM( str r1, [r0], #-2048 ) @ linux version
131 THUMB( str r1, [r0] ) @ linux version
132 THUMB( sub r0, r0, #2048 )
131 133
132 bic r3, r1, #0x000003f0 134 bic r3, r1, #0x000003f0
133 bic r3, r3, #PTE_TYPE_MASK 135 bic r3, r3, #PTE_TYPE_MASK
@@ -232,7 +234,6 @@ __v7_setup:
232 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 234 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
233 mov r10, #0x1f @ domains 0, 1 = manager 235 mov r10, #0x1f @ domains 0, 1 = manager
234 mcr p15, 0, r10, c3, c0, 0 @ load domain access register 236 mcr p15, 0, r10, c3, c0, 0 @ load domain access register
235#endif
236 /* 237 /*
237 * Memory region attributes with SCTLR.TRE=1 238 * Memory region attributes with SCTLR.TRE=1
238 * 239 *
@@ -265,6 +266,7 @@ __v7_setup:
265 ldr r6, =0x40e040e0 @ NMRR 266 ldr r6, =0x40e040e0 @ NMRR
266 mcr p15, 0, r5, c10, c2, 0 @ write PRRR 267 mcr p15, 0, r5, c10, c2, 0 @ write PRRR
267 mcr p15, 0, r6, c10, c2, 1 @ write NMRR 268 mcr p15, 0, r6, c10, c2, 1 @ write NMRR
269#endif
268 adr r5, v7_crval 270 adr r5, v7_crval
269 ldmia r5, {r5, r6} 271 ldmia r5, {r5, r6}
270#ifdef CONFIG_CPU_ENDIAN_BE8 272#ifdef CONFIG_CPU_ENDIAN_BE8
@@ -273,6 +275,7 @@ __v7_setup:
273 mrc p15, 0, r0, c1, c0, 0 @ read control register 275 mrc p15, 0, r0, c1, c0, 0 @ read control register
274 bic r0, r0, r5 @ clear bits them 276 bic r0, r0, r5 @ clear bits them
275 orr r0, r0, r6 @ set them 277 orr r0, r0, r6 @ set them
278 THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions
276 mov pc, lr @ return to head.S:__ret 279 mov pc, lr @ return to head.S:__ret
277ENDPROC(__v7_setup) 280ENDPROC(__v7_setup)
278 281
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 8986b7412235..ca5c7c226341 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -9,6 +9,7 @@ choice
9config ARCH_MX1 9config ARCH_MX1
10 bool "MX1-based" 10 bool "MX1-based"
11 select CPU_ARM920T 11 select CPU_ARM920T
12 select COMMON_CLKDEV
12 help 13 help
13 This enables support for systems based on the Freescale i.MX1 family 14 This enables support for systems based on the Freescale i.MX1 family
14 15
@@ -19,6 +20,13 @@ config ARCH_MX2
19 help 20 help
20 This enables support for systems based on the Freescale i.MX2 family 21 This enables support for systems based on the Freescale i.MX2 family
21 22
23config ARCH_MX25
24 bool "MX25-based"
25 select CPU_ARM926T
26 select COMMON_CLKDEV
27 help
28 This enables support for systems based on the Freescale i.MX25 family
29
22config ARCH_MX3 30config ARCH_MX3
23 bool "MX3-based" 31 bool "MX3-based"
24 select CPU_V6 32 select CPU_V6
@@ -26,11 +34,20 @@ config ARCH_MX3
26 help 34 help
27 This enables support for systems based on the Freescale i.MX3 family 35 This enables support for systems based on the Freescale i.MX3 family
28 36
37config ARCH_MXC91231
38 bool "MXC91231-based"
39 select CPU_V6
40 select COMMON_CLKDEV
41 help
42 This enables support for systems based on the Freescale MXC91231 family
43
29endchoice 44endchoice
30 45
31source "arch/arm/mach-mx1/Kconfig" 46source "arch/arm/mach-mx1/Kconfig"
32source "arch/arm/mach-mx2/Kconfig" 47source "arch/arm/mach-mx2/Kconfig"
33source "arch/arm/mach-mx3/Kconfig" 48source "arch/arm/mach-mx3/Kconfig"
49source "arch/arm/mach-mx25/Kconfig"
50source "arch/arm/mach-mxc91231/Kconfig"
34 51
35endmenu 52endmenu
36 53
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 92e13566cd4f..9e8fbd57495c 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -39,6 +39,7 @@
39#include <linux/string.h> 39#include <linux/string.h>
40 40
41#include <mach/clock.h> 41#include <mach/clock.h>
42#include <mach/hardware.h>
42 43
43static LIST_HEAD(clocks); 44static LIST_HEAD(clocks);
44static DEFINE_MUTEX(clocks_mutex); 45static DEFINE_MUTEX(clocks_mutex);
@@ -47,76 +48,6 @@ static DEFINE_MUTEX(clocks_mutex);
47 * Standard clock functions defined in include/linux/clk.h 48 * Standard clock functions defined in include/linux/clk.h
48 *-------------------------------------------------------------------------*/ 49 *-------------------------------------------------------------------------*/
49 50
50/*
51 * All the code inside #ifndef CONFIG_COMMON_CLKDEV can be removed once all
52 * MXC architectures have switched to using clkdev.
53 */
54#ifndef CONFIG_COMMON_CLKDEV
55/*
56 * Retrieve a clock by name.
57 *
58 * Note that we first try to use device id on the bus
59 * and clock name. If this fails, we try to use "<name>.<id>". If this fails,
60 * we try to use clock name only.
61 * The reference count to the clock's module owner ref count is incremented.
62 */
63struct clk *clk_get(struct device *dev, const char *id)
64{
65 struct clk *p, *clk = ERR_PTR(-ENOENT);
66 int idno;
67 const char *str;
68
69 if (id == NULL)
70 return clk;
71
72 if (dev == NULL || dev->bus != &platform_bus_type)
73 idno = -1;
74 else
75 idno = to_platform_device(dev)->id;
76
77 mutex_lock(&clocks_mutex);
78
79 list_for_each_entry(p, &clocks, node) {
80 if (p->id == idno &&
81 strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
82 clk = p;
83 goto found;
84 }
85 }
86
87 str = strrchr(id, '.');
88 if (str) {
89 int cnt = str - id;
90 str++;
91 idno = simple_strtol(str, NULL, 10);
92 list_for_each_entry(p, &clocks, node) {
93 if (p->id == idno &&
94 strlen(p->name) == cnt &&
95 strncmp(id, p->name, cnt) == 0 &&
96 try_module_get(p->owner)) {
97 clk = p;
98 goto found;
99 }
100 }
101 }
102
103 list_for_each_entry(p, &clocks, node) {
104 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
105 clk = p;
106 goto found;
107 }
108 }
109
110 printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id);
111
112found:
113 mutex_unlock(&clocks_mutex);
114
115 return clk;
116}
117EXPORT_SYMBOL(clk_get);
118#endif
119
120static void __clk_disable(struct clk *clk) 51static void __clk_disable(struct clk *clk)
121{ 52{
122 if (clk == NULL || IS_ERR(clk)) 53 if (clk == NULL || IS_ERR(clk))
@@ -193,16 +124,6 @@ unsigned long clk_get_rate(struct clk *clk)
193} 124}
194EXPORT_SYMBOL(clk_get_rate); 125EXPORT_SYMBOL(clk_get_rate);
195 126
196#ifndef CONFIG_COMMON_CLKDEV
197/* Decrement the clock's module reference count */
198void clk_put(struct clk *clk)
199{
200 if (clk && !IS_ERR(clk))
201 module_put(clk->owner);
202}
203EXPORT_SYMBOL(clk_put);
204#endif
205
206/* Round the requested clock rate to the nearest supported 127/* Round the requested clock rate to the nearest supported
207 * rate that is less than or equal to the requested rate. 128 * rate that is less than or equal to the requested rate.
208 * This is dependent on the clock's current parent. 129 * This is dependent on the clock's current parent.
@@ -265,80 +186,6 @@ struct clk *clk_get_parent(struct clk *clk)
265} 186}
266EXPORT_SYMBOL(clk_get_parent); 187EXPORT_SYMBOL(clk_get_parent);
267 188
268#ifndef CONFIG_COMMON_CLKDEV
269/*
270 * Add a new clock to the clock tree.
271 */
272int clk_register(struct clk *clk)
273{
274 if (clk == NULL || IS_ERR(clk))
275 return -EINVAL;
276
277 mutex_lock(&clocks_mutex);
278 list_add(&clk->node, &clocks);
279 mutex_unlock(&clocks_mutex);
280
281 return 0;
282}
283EXPORT_SYMBOL(clk_register);
284
285/* Remove a clock from the clock tree */
286void clk_unregister(struct clk *clk)
287{
288 if (clk == NULL || IS_ERR(clk))
289 return;
290
291 mutex_lock(&clocks_mutex);
292 list_del(&clk->node);
293 mutex_unlock(&clocks_mutex);
294}
295EXPORT_SYMBOL(clk_unregister);
296
297#ifdef CONFIG_PROC_FS
298static int mxc_clock_read_proc(char *page, char **start, off_t off,
299 int count, int *eof, void *data)
300{
301 struct clk *clkp;
302 char *p = page;
303 int len;
304
305 list_for_each_entry(clkp, &clocks, node) {
306 p += sprintf(p, "%s-%d:\t\t%lu, %d", clkp->name, clkp->id,
307 clk_get_rate(clkp), clkp->usecount);
308 if (clkp->parent)
309 p += sprintf(p, ", %s-%d\n", clkp->parent->name,
310 clkp->parent->id);
311 else
312 p += sprintf(p, "\n");
313 }
314
315 len = (p - page) - off;
316 if (len < 0)
317 len = 0;
318
319 *eof = (len <= count) ? 1 : 0;
320 *start = page + off;
321
322 return len;
323}
324
325static int __init mxc_setup_proc_entry(void)
326{
327 struct proc_dir_entry *res;
328
329 res = create_proc_read_entry("cpu/clocks", 0, NULL,
330 mxc_clock_read_proc, NULL);
331 if (!res) {
332 printk(KERN_ERR "Failed to create proc/cpu/clocks\n");
333 return -ENOMEM;
334 }
335 return 0;
336}
337
338late_initcall(mxc_setup_proc_entry);
339#endif /* CONFIG_PROC_FS */
340#endif
341
342/* 189/*
343 * Get the resulting clock rate from a PLL register value and the input 190 * Get the resulting clock rate from a PLL register value and the input
344 * frequency. PLLs with this register layout can at least be found on 191 * frequency. PLLs with this register layout can at least be found on
@@ -363,12 +210,11 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
363 210
364 mfn_abs = mfn; 211 mfn_abs = mfn;
365 212
366#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21 213 /* On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
367 if (mfn >= 0x200) { 214 * 2's complements number
368 mfn |= 0xFFFFFE00; 215 */
369 mfn_abs = -mfn; 216 if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
370 } 217 mfn_abs = 0x400 - mfn;
371#endif
372 218
373 freq *= 2; 219 freq *= 2;
374 freq /= pd + 1; 220 freq /= pd + 1;
@@ -376,8 +222,10 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
376 ll = (unsigned long long)freq * mfn_abs; 222 ll = (unsigned long long)freq * mfn_abs;
377 223
378 do_div(ll, mfd + 1); 224 do_div(ll, mfd + 1);
379 if (mfn < 0) 225
226 if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
380 ll = -ll; 227 ll = -ll;
228
381 ll = (freq * mfi) + ll; 229 ll = (freq * mfi) + ll;
382 230
383 return ll; 231 return ll;
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 7506d963be4b..cfc4a8b43e6a 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -29,6 +29,23 @@
29static struct mxc_gpio_port *mxc_gpio_ports; 29static struct mxc_gpio_port *mxc_gpio_ports;
30static int gpio_table_size; 30static int gpio_table_size;
31 31
32#define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2())
33
34#define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00)
35#define GPIO_GDIR (cpu_is_mx1_mx2() ? 0x00 : 0x04)
36#define GPIO_PSR (cpu_is_mx1_mx2() ? 0x24 : 0x08)
37#define GPIO_ICR1 (cpu_is_mx1_mx2() ? 0x28 : 0x0C)
38#define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10)
39#define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14)
40#define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
41#define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
42
43#define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0)
44#define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1)
45#define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2)
46#define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3)
47#define GPIO_INT_NONE 0x4
48
32/* Note: This driver assumes 32 GPIOs are handled in one register */ 49/* Note: This driver assumes 32 GPIOs are handled in one register */
33 50
34static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) 51static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
@@ -162,7 +179,6 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
162 } 179 }
163} 180}
164 181
165#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX1)
166/* MX1 and MX3 has one interrupt *per* gpio port */ 182/* MX1 and MX3 has one interrupt *per* gpio port */
167static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) 183static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
168{ 184{
@@ -174,9 +190,7 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
174 190
175 mxc_gpio_irq_handler(port, irq_stat); 191 mxc_gpio_irq_handler(port, irq_stat);
176} 192}
177#endif
178 193
179#ifdef CONFIG_ARCH_MX2
180/* MX2 has one interrupt *for all* gpio ports */ 194/* MX2 has one interrupt *for all* gpio ports */
181static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) 195static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
182{ 196{
@@ -195,7 +209,6 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
195 mxc_gpio_irq_handler(&port[i], irq_stat); 209 mxc_gpio_irq_handler(&port[i], irq_stat);
196 } 210 }
197} 211}
198#endif
199 212
200static struct irq_chip gpio_irq_chip = { 213static struct irq_chip gpio_irq_chip = {
201 .ack = gpio_ack_irq, 214 .ack = gpio_ack_irq,
@@ -284,17 +297,18 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
284 /* its a serious configuration bug when it fails */ 297 /* its a serious configuration bug when it fails */
285 BUG_ON( gpiochip_add(&port[i].chip) < 0 ); 298 BUG_ON( gpiochip_add(&port[i].chip) < 0 );
286 299
287#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX1) 300 if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25()) {
288 /* setup one handler for each entry */ 301 /* setup one handler for each entry */
289 set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); 302 set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
290 set_irq_data(port[i].irq, &port[i]); 303 set_irq_data(port[i].irq, &port[i]);
291#endif 304 }
305 }
306
307 if (cpu_is_mx2()) {
308 /* setup one handler for all GPIO interrupts */
309 set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
310 set_irq_data(port[0].irq, port);
292 } 311 }
293 312
294#ifdef CONFIG_ARCH_MX2
295 /* setup one handler for all GPIO interrupts */
296 set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
297 set_irq_data(port[0].irq, port);
298#endif
299 return 0; 313 return 0;
300} 314}
diff --git a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
index 8769e910e559..0376c133c9f4 100644
--- a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
+++ b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
@@ -12,11 +12,4 @@
12#ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__ 12#ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
13#define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__ 13#define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
14 14
15#include <mach/hardware.h>
16
17/* mandatory for CONFIG_DEBUG_LL */
18
19#define MXC_LL_UART_PADDR UART1_BASE_ADDR
20#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
21
22#endif 15#endif
diff --git a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
new file mode 100644
index 000000000000..a1fd5830af48
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2009 Eric Benard - eric@eukrea.com
3 *
4 * Based on board-pcm038.h which is :
5 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22#ifndef __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__
23#define __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__
24
25#ifndef __ASSEMBLY__
26/*
27 * This CPU module needs a baseboard to work. After basic initializing
28 * its own devices, it calls baseboard's init function.
29 * TODO: Add your own baseboard init function and call it from
30 * inside eukrea_cpuimx27_init().
31 *
32 * This example here is for the development board. Refer
33 * eukrea_mbimx27-baseboard.c
34 */
35
36extern void eukrea_mbimx27_baseboard_init(void);
37
38#endif
39
40#endif /* __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx21ads.h b/arch/arm/plat-mxc/include/mach/board-mx21ads.h
index 06701df74c42..0cf4fa29510c 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx21ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx21ads.h
@@ -15,12 +15,6 @@
15#define __ASM_ARCH_MXC_BOARD_MX21ADS_H__ 15#define __ASM_ARCH_MXC_BOARD_MX21ADS_H__
16 16
17/* 17/*
18 * MXC UART EVB board level configurations
19 */
20#define MXC_LL_UART_PADDR UART1_BASE_ADDR
21#define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR)
22
23/*
24 * Memory-mapped I/O on MX21ADS base board 18 * Memory-mapped I/O on MX21ADS base board
25 */ 19 */
26#define MX21ADS_MMIO_BASE_ADDR 0xF5000000 20#define MX21ADS_MMIO_BASE_ADDR 0xF5000000
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
index d42f4e6116f8..7776d230327f 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
@@ -26,12 +26,6 @@
26 MXC_MAX_VIRTUAL_INTS) 26 MXC_MAX_VIRTUAL_INTS)
27 27
28/* 28/*
29 * MXC UART EVB board level configurations
30 */
31#define MXC_LL_UART_PADDR UART1_BASE_ADDR
32#define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR)
33
34/*
35 * @name Memory Size parameters 29 * @name Memory Size parameters
36 */ 30 */
37 31
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27lite.h b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
index a870f8ea2443..ea87551d2736 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27lite.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
@@ -11,9 +11,4 @@
11#ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__ 11#ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__
12#define __ASM_ARCH_MXC_BOARD_MX27LITE_H__ 12#define __ASM_ARCH_MXC_BOARD_MX27LITE_H__
13 13
14/* mandatory for CONFIG_DEBUG_LL */
15
16#define MXC_LL_UART_PADDR UART1_BASE_ADDR
17#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
18
19#endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */ 14#endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
index 552b55d714d8..fec1bcfa9164 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
@@ -11,9 +11,4 @@
11#ifndef __ASM_ARCH_MXC_BOARD_MX27PDK_H__ 11#ifndef __ASM_ARCH_MXC_BOARD_MX27PDK_H__
12#define __ASM_ARCH_MXC_BOARD_MX27PDK_H__ 12#define __ASM_ARCH_MXC_BOARD_MX27PDK_H__
13 13
14/* mandatory for CONFIG_DEBUG_LL */
15
16#define MXC_LL_UART_PADDR UART1_BASE_ADDR
17#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
18
19#endif /* __ASM_ARCH_MXC_BOARD_MX27PDK_H__ */ 14#endif /* __ASM_ARCH_MXC_BOARD_MX27PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
index 06e6895f7f65..2cbfa35e82ff 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -114,9 +114,4 @@
114 114
115#define MXC_MAX_EXP_IO_LINES 16 115#define MXC_MAX_EXP_IO_LINES 16
116 116
117/* mandatory for CONFIG_DEBUG_LL */
118
119#define MXC_LL_UART_PADDR UART1_BASE_ADDR
120#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
121
122#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ 117#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
index 78cf31e22e4d..eb5a5024622e 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
@@ -22,11 +22,6 @@
22#ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ 22#ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
23#define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ 23#define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
24 24
25/* mandatory for CONFIG_LL_DEBUG */
26
27#define MXC_LL_UART_PADDR UART1_BASE_ADDR
28#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000)
29
30#ifndef __ASSEMBLY__ 25#ifndef __ASSEMBLY__
31 26
32enum mx31lilly_boards { 27enum mx31lilly_boards {
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
index 52fbdf2d6f26..8e64325d6905 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lite.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
@@ -11,8 +11,5 @@
11#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__ 11#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__
12#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__ 12#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__
13 13
14#define MXC_LL_UART_PADDR UART1_BASE_ADDR
15#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
16
17#endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */ 14#endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */
18 15
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
index 303fd2434a21..d5be6b5a6acf 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
@@ -19,11 +19,6 @@
19#ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ 19#ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
20#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ 20#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
21 21
22/* mandatory for CONFIG_DEBUG_LL */
23
24#define MXC_LL_UART_PADDR UART1_BASE_ADDR
25#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000)
26
27#ifndef __ASSEMBLY__ 22#ifndef __ASSEMBLY__
28 23
29enum mx31moboard_boards { 24enum mx31moboard_boards {
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
index 519bab3eb28b..2bbd6ed17f50 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
@@ -11,11 +11,6 @@
11#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ 11#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
12#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ 12#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
13 13
14/* mandatory for CONFIG_DEBUG_LL */
15
16#define MXC_LL_UART_PADDR UART1_BASE_ADDR
17#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
18
19/* Definitions for components on the Debug board */ 14/* Definitions for components on the Debug board */
20 15
21/* Base address of CPLD controller on the Debug board */ 16/* Base address of CPLD controller on the Debug board */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
index 1111037d6d9d..383f1c04df06 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
@@ -19,9 +19,4 @@
19#ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__ 19#ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__
20#define __ASM_ARCH_MXC_BOARD_MX35PDK_H__ 20#define __ASM_ARCH_MXC_BOARD_MX35PDK_H__
21 21
22/* mandatory for CONFIG_DEBUG_LL */
23
24#define MXC_LL_UART_PADDR UART1_BASE_ADDR
25#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
26
27#endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */ 22#endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm037.h b/arch/arm/plat-mxc/include/mach/board-pcm037.h
index f0a1fa1938a2..13411709b13a 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm037.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm037.h
@@ -19,9 +19,4 @@
19#ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__ 19#ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__
20#define __ASM_ARCH_MXC_BOARD_PCM037_H__ 20#define __ASM_ARCH_MXC_BOARD_PCM037_H__
21 21
22/* mandatory for CONFIG_DEBUG_LL */
23
24#define MXC_LL_UART_PADDR UART1_BASE_ADDR
25#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
26
27#endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */ 22#endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm038.h b/arch/arm/plat-mxc/include/mach/board-pcm038.h
index 4fcd7499e092..410f9786ed22 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm038.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm038.h
@@ -19,11 +19,6 @@
19#ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__ 19#ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__
20#define __ASM_ARCH_MXC_BOARD_PCM038_H__ 20#define __ASM_ARCH_MXC_BOARD_PCM038_H__
21 21
22/* mandatory for CONFIG_DEBUG_LL */
23
24#define MXC_LL_UART_PADDR UART1_BASE_ADDR
25#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000)
26
27#ifndef __ASSEMBLY__ 22#ifndef __ASSEMBLY__
28/* 23/*
29 * This CPU module needs a baseboard to work. After basic initializing 24 * This CPU module needs a baseboard to work. After basic initializing
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm043.h b/arch/arm/plat-mxc/include/mach/board-pcm043.h
index 15fbdf16abcd..1ac4e1682e5c 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm043.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm043.h
@@ -19,9 +19,4 @@
19#ifndef __ASM_ARCH_MXC_BOARD_PCM043_H__ 19#ifndef __ASM_ARCH_MXC_BOARD_PCM043_H__
20#define __ASM_ARCH_MXC_BOARD_PCM043_H__ 20#define __ASM_ARCH_MXC_BOARD_PCM043_H__
21 21
22/* mandatory for CONFIG_LL_DEBUG */
23
24#define MXC_LL_UART_PADDR UART1_BASE_ADDR
25#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
26
27#endif /* __ASM_ARCH_MXC_BOARD_PCM043_H__ */ 22#endif /* __ASM_ARCH_MXC_BOARD_PCM043_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-qong.h b/arch/arm/plat-mxc/include/mach/board-qong.h
index 04033ec637d2..6d88c7af4b23 100644
--- a/arch/arm/plat-mxc/include/mach/board-qong.h
+++ b/arch/arm/plat-mxc/include/mach/board-qong.h
@@ -11,11 +11,6 @@
11#ifndef __ASM_ARCH_MXC_BOARD_QONG_H__ 11#ifndef __ASM_ARCH_MXC_BOARD_QONG_H__
12#define __ASM_ARCH_MXC_BOARD_QONG_H__ 12#define __ASM_ARCH_MXC_BOARD_QONG_H__
13 13
14/* mandatory for CONFIG_DEBUG_LL */
15
16#define MXC_LL_UART_PADDR UART1_BASE_ADDR
17#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
18
19/* NOR FLASH */ 14/* NOR FLASH */
20#define QONG_NOR_SIZE (128*1024*1024) 15#define QONG_NOR_SIZE (128*1024*1024)
21 16
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 02c3cd004db3..286cb9b0a25b 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -16,18 +16,33 @@ struct clk;
16 16
17extern void mx1_map_io(void); 17extern void mx1_map_io(void);
18extern void mx21_map_io(void); 18extern void mx21_map_io(void);
19extern void mx25_map_io(void);
19extern void mx27_map_io(void); 20extern void mx27_map_io(void);
20extern void mx31_map_io(void); 21extern void mx31_map_io(void);
21extern void mx35_map_io(void); 22extern void mx35_map_io(void);
22extern void mxc_init_irq(void); 23extern void mxc91231_map_io(void);
23extern void mxc_timer_init(struct clk *timer_clk); 24extern void mxc_init_irq(void __iomem *);
25extern void mx1_init_irq(void);
26extern void mx21_init_irq(void);
27extern void mx25_init_irq(void);
28extern void mx27_init_irq(void);
29extern void mx31_init_irq(void);
30extern void mx35_init_irq(void);
31extern void mxc91231_init_irq(void);
32extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
24extern int mx1_clocks_init(unsigned long fref); 33extern int mx1_clocks_init(unsigned long fref);
25extern int mx21_clocks_init(unsigned long lref, unsigned long fref); 34extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
35extern int mx25_clocks_init(unsigned long fref);
26extern int mx27_clocks_init(unsigned long fref); 36extern int mx27_clocks_init(unsigned long fref);
27extern int mx31_clocks_init(unsigned long fref); 37extern int mx31_clocks_init(unsigned long fref);
28extern int mx35_clocks_init(void); 38extern int mx35_clocks_init(void);
39extern int mxc91231_clocks_init(unsigned long fref);
29extern int mxc_register_gpios(void); 40extern int mxc_register_gpios(void);
30extern int mxc_register_device(struct platform_device *pdev, void *data); 41extern int mxc_register_device(struct platform_device *pdev, void *data);
31extern void mxc_set_cpu_type(unsigned int type); 42extern void mxc_set_cpu_type(unsigned int type);
43extern void mxc_arch_reset_init(void __iomem *);
44extern void mxc91231_power_off(void);
45extern void mxc91231_arch_reset(int, const char *);
46extern void mxc91231_prepare_idle(void);
32 47
33#endif 48#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index bbc5f6753cfb..15b2b148a105 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -11,52 +11,52 @@
11 * 11 *
12 */ 12 */
13 13
14#include <mach/hardware.h> 14#ifdef CONFIG_ARCH_MX1
15 15#include <mach/mx1.h>
16#ifdef CONFIG_MACH_MX31ADS 16#define UART_PADDR UART1_BASE_ADDR
17#include <mach/board-mx31ads.h> 17#define UART_VADDR IO_ADDRESS(UART1_BASE_ADDR)
18#endif
19#ifdef CONFIG_MACH_PCM037
20#include <mach/board-pcm037.h>
21#endif
22#ifdef CONFIG_MACH_MX31LITE
23#include <mach/board-mx31lite.h>
24#endif
25#ifdef CONFIG_MACH_MX27ADS
26#include <mach/board-mx27ads.h>
27#endif
28#ifdef CONFIG_MACH_MX21ADS
29#include <mach/board-mx21ads.h>
30#endif 18#endif
31#ifdef CONFIG_MACH_PCM038 19
32#include <mach/board-pcm038.h> 20#ifdef CONFIG_ARCH_MX25
21#ifdef UART_PADDR
22#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
33#endif 23#endif
34#ifdef CONFIG_MACH_MX31_3DS 24#include <mach/mx25.h>
35#include <mach/board-mx31pdk.h> 25#define UART_PADDR UART1_BASE_ADDR
26#define UART_VADDR MX25_AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
36#endif 27#endif
37#ifdef CONFIG_MACH_QONG 28
38#include <mach/board-qong.h> 29#ifdef CONFIG_ARCH_MX2
30#ifdef UART_PADDR
31#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
39#endif 32#endif
40#ifdef CONFIG_MACH_PCM043 33#include <mach/mx2x.h>
41#include <mach/board-pcm043.h> 34#define UART_PADDR UART1_BASE_ADDR
35#define UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR)
42#endif 36#endif
43#ifdef CONFIG_MACH_MX27_3DS 37
44#include <mach/board-mx27pdk.h> 38#ifdef CONFIG_ARCH_MX3
39#ifdef UART_PADDR
40#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
45#endif 41#endif
46#ifdef CONFIG_MACH_ARMADILLO5X0 42#include <mach/mx3x.h>
47#include <mach/board-armadillo5x0.h> 43#define UART_PADDR UART1_BASE_ADDR
44#define UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
48#endif 45#endif
49#ifdef CONFIG_MACH_MX35_3DS 46
50#include <mach/board-mx35pdk.h> 47#ifdef CONFIG_ARCH_MXC91231
48#ifdef UART_PADDR
49#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
51#endif 50#endif
52#ifdef CONFIG_MACH_MX27LITE 51#include <mach/mxc91231.h>
53#include <mach/board-mx27lite.h> 52#define UART_PADDR MXC91231_UART2_BASE_ADDR
53#define UART_VADDR MXC91231_AIPS1_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
54#endif 54#endif
55 .macro addruart,rx 55 .macro addruart,rx
56 mrc p15, 0, \rx, c1, c0 56 mrc p15, 0, \rx, c1, c0
57 tst \rx, #1 @ MMU enabled? 57 tst \rx, #1 @ MMU enabled?
58 ldreq \rx, =MXC_LL_UART_PADDR @ physical 58 ldreq \rx, =UART_PADDR @ physical
59 ldrne \rx, =MXC_LL_UART_VADDR @ virtual 59 ldrne \rx, =UART_VADDR @ virtual
60 .endm 60 .endm
61 61
62 .macro senduart,rd,rx 62 .macro senduart,rd,rx
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 5f01d60da845..7cf290efe768 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -18,7 +18,8 @@
18 .endm 18 .endm
19 19
20 .macro get_irqnr_preamble, base, tmp 20 .macro get_irqnr_preamble, base, tmp
21 ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR) 21 ldr \base, =avic_base
22 ldr \base, [\base]
22#ifdef CONFIG_MXC_IRQ_PRIOR 23#ifdef CONFIG_MXC_IRQ_PRIOR
23 ldr r4, [\base, #AVIC_NIMASK] 24 ldr r4, [\base, #AVIC_NIMASK]
24#endif 25#endif
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 42e4ee37ca1f..78db75475f69 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -42,6 +42,14 @@
42# include <mach/mx1.h> 42# include <mach/mx1.h>
43#endif 43#endif
44 44
45#ifdef CONFIG_ARCH_MX25
46# include <mach/mx25.h>
47#endif
48
49#ifdef CONFIG_ARCH_MXC91231
50# include <mach/mxc91231.h>
51#endif
52
45#include <mach/mxc.h> 53#include <mach/mxc.h>
46 54
47#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ 55#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h
index 9f0101157ec1..5263506b7ddf 100644
--- a/arch/arm/plat-mxc/include/mach/imxfb.h
+++ b/arch/arm/plat-mxc/include/mach/imxfb.h
@@ -2,6 +2,8 @@
2 * This structure describes the machine which we are running on. 2 * This structure describes the machine which we are running on.
3 */ 3 */
4 4
5#include <linux/fb.h>
6
5#define PCR_TFT (1 << 31) 7#define PCR_TFT (1 << 31)
6#define PCR_COLOR (1 << 30) 8#define PCR_COLOR (1 << 30)
7#define PCR_PBSIZ_1 (0 << 28) 9#define PCR_PBSIZ_1 (0 << 28)
@@ -13,7 +15,8 @@
13#define PCR_BPIX_4 (2 << 25) 15#define PCR_BPIX_4 (2 << 25)
14#define PCR_BPIX_8 (3 << 25) 16#define PCR_BPIX_8 (3 << 25)
15#define PCR_BPIX_12 (4 << 25) 17#define PCR_BPIX_12 (4 << 25)
16#define PCR_BPIX_16 (4 << 25) 18#define PCR_BPIX_16 (5 << 25)
19#define PCR_BPIX_18 (6 << 25)
17#define PCR_PIXPOL (1 << 24) 20#define PCR_PIXPOL (1 << 24)
18#define PCR_FLMPOL (1 << 23) 21#define PCR_FLMPOL (1 << 23)
19#define PCR_LPPOL (1 << 22) 22#define PCR_LPPOL (1 << 22)
@@ -46,29 +49,21 @@
46#define DMACR_HM(x) (((x) & 0xf) << 16) 49#define DMACR_HM(x) (((x) & 0xf) << 16)
47#define DMACR_TM(x) ((x) & 0xf) 50#define DMACR_TM(x) ((x) & 0xf)
48 51
49struct imx_fb_platform_data { 52struct imx_fb_videomode {
50 u_long pixclock; 53 struct fb_videomode mode;
51 54 u32 pcr;
52 u_short xres; 55 unsigned char bpp;
53 u_short yres; 56};
54
55 u_int nonstd;
56 u_char bpp;
57 u_char hsync_len;
58 u_char left_margin;
59 u_char right_margin;
60 57
61 u_char vsync_len; 58struct imx_fb_platform_data {
62 u_char upper_margin; 59 struct imx_fb_videomode *mode;
63 u_char lower_margin; 60 int num_modes;
64 u_char sync;
65 61
66 u_int cmap_greyscale:1, 62 u_int cmap_greyscale:1,
67 cmap_inverse:1, 63 cmap_inverse:1,
68 cmap_static:1, 64 cmap_static:1,
69 unused:29; 65 unused:29;
70 66
71 u_int pcr;
72 u_int pwmr; 67 u_int pwmr;
73 u_int lscr1; 68 u_int lscr1;
74 u_int dmacr; 69 u_int dmacr;
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
new file mode 100644
index 000000000000..810c47f56e77
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -0,0 +1,517 @@
1/*
2 * arch/arm/plat-mxc/include/mach/iomux-mx25.h
3 *
4 * Copyright (C) 2009 by Lothar Wassmann <LW@KARO-electronics.de>
5 *
6 * based on arch/arm/mach-mx25/mx25_pins.h
7 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
8 * and
9 * arch/arm/plat-mxc/include/mach/iomux-mx35.h
10 * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
11 *
12 * The code contained herein is licensed under the GNU General Public
13 * License. You may obtain a copy of the GNU General Public License
14 * Version 2 or later at the following locations:
15 *
16 * http://www.opensource.org/licenses/gpl-license.html
17 * http://www.gnu.org/copyleft/gpl.html
18 */
19#ifndef __IOMUX_MX25_H__
20#define __IOMUX_MX25_H__
21
22#include <mach/iomux-v3.h>
23
24#ifndef GPIO_PORTA
25#error Please include mach/iomux.h
26#endif
27
28/*
29 *
30 * @brief MX25 I/O Pin List
31 *
32 * @ingroup GPIO_MX25
33 */
34
35#ifndef __ASSEMBLY__
36
37/*
38 * IOMUX/PAD Bit field definitions
39 */
40
41#define MX25_PAD_A10__A10 IOMUX_PAD(0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL)
42#define MX25_PAD_A10__GPIO_4_0 IOMUX_PAD(0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL)
43
44#define MX25_PAD_A13__A13 IOMUX_PAD(0x22C, 0x00c, 0x00, 0, 0, NO_PAD_CTRL)
45#define MX25_PAD_A13__GPIO_4_1 IOMUX_PAD(0x22C, 0x00c, 0x05, 0, 0, NO_PAD_CTRL)
46
47#define MX25_PAD_A14__A14 IOMUX_PAD(0x230, 0x010, 0x10, 0, 0, NO_PAD_CTRL)
48#define MX25_PAD_A14__GPIO_2_0 IOMUX_PAD(0x230, 0x010, 0x15, 0, 0, NO_PAD_CTRL)
49
50#define MX25_PAD_A15__A15 IOMUX_PAD(0x234, 0x014, 0x10, 0, 0, NO_PAD_CTRL)
51#define MX25_PAD_A15__GPIO_2_1 IOMUX_PAD(0x234, 0x014, 0x15, 0, 0, NO_PAD_CTRL)
52
53#define MX25_PAD_A16__A16 IOMUX_PAD(0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL)
54#define MX25_PAD_A16__GPIO_2_2 IOMUX_PAD(0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL)
55
56#define MX25_PAD_A17__A17 IOMUX_PAD(0x238, 0x01c, 0x10, 0, 0, NO_PAD_CTRL)
57#define MX25_PAD_A17__GPIO_2_3 IOMUX_PAD(0x238, 0x01c, 0x15, 0, 0, NO_PAD_CTRL)
58
59#define MX25_PAD_A18__A18 IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL)
60#define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL)
61#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTL)
62
63#define MX25_PAD_A19__A19 IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL)
64#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTL)
65#define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL)
66
67#define MX25_PAD_A20__A20 IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL)
68#define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL)
69#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTL)
70
71#define MX25_PAD_A21__A21 IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL)
72#define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL)
73#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTL)
74
75#define MX25_PAD_A22__A22 IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL)
76#define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL)
77
78#define MX25_PAD_A23__A23 IOMUX_PAD(0x24c, 0x034, 0x10, 0, 0, NO_PAD_CTRL)
79#define MX25_PAD_A23__GPIO_2_9 IOMUX_PAD(0x24c, 0x034, 0x15, 0, 0, NO_PAD_CTRL)
80
81#define MX25_PAD_A24__A24 IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL)
82#define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL)
83#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTL)
84
85#define MX25_PAD_A25__A25 IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL)
86#define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL)
87#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTL)
88
89#define MX25_PAD_EB0__EB0 IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL)
90#define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL)
91#define MX25_PAD_EB0__GPIO_2_12 IOMUX_PAD(0x258, 0x040, 0x15, 0, 0, NO_PAD_CTRL)
92
93#define MX25_PAD_EB1__EB1 IOMUX_PAD(0x25c, 0x044, 0x10, 0, 0, NO_PAD_CTRL)
94#define MX25_PAD_EB1__AUD4_RXD IOMUX_PAD(0x25c, 0x044, 0x14, 0x460, 0, NO_PAD_CTRL)
95#define MX25_PAD_EB1__GPIO_2_13 IOMUX_PAD(0x25c, 0x044, 0x15, 0, 0, NO_PAD_CTRL)
96
97#define MX25_PAD_OE__OE IOMUX_PAD(0x260, 0x048, 0x10, 0, 0, NO_PAD_CTRL)
98#define MX25_PAD_OE__AUD4_TXC IOMUX_PAD(0x260, 0x048, 0x14, 0, 0, NO_PAD_CTRL)
99#define MX25_PAD_OE__GPIO_2_14 IOMUX_PAD(0x260, 0x048, 0x15, 0, 0, NO_PAD_CTRL)
100
101#define MX25_PAD_CS0__CS0 IOMUX_PAD(0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL)
102#define MX25_PAD_CS0__GPIO_4_2 IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL)
103
104#define MX25_PAD_CS1__CS1 IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL)
105#define MX25_PAD_CS1__GPIO_4_3 IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL)
106
107#define MX25_PAD_CS4__CS4 IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL)
108#define MX25_PAD_CS4__UART5_CTS IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL)
109#define MX25_PAD_CS4__GPIO_3_20 IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL)
110
111#define MX25_PAD_CS5__CS5 IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL)
112#define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL)
113#define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL)
114
115#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTL)
116#define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL)
117
118#define MX25_PAD_ECB__ECB IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL)
119#define MX25_PAD_ECB__UART5_TXD_MUX IOMUX_PAD(0x270, 0x060, 0x13, 0, 0, NO_PAD_CTRL)
120#define MX25_PAD_ECB__GPIO_3_23 IOMUX_PAD(0x270, 0x060, 0x15, 0, 0, NO_PAD_CTRL)
121
122#define MX25_PAD_LBA__LBA IOMUX_PAD(0x274, 0x064, 0x10, 0, 0, NO_PAD_CTRL)
123#define MX25_PAD_LBA__UART5_RXD_MUX IOMUX_PAD(0x274, 0x064, 0x13, 0x578, 0, NO_PAD_CTRL)
124#define MX25_PAD_LBA__GPIO_3_24 IOMUX_PAD(0x274, 0x064, 0x15, 0, 0, NO_PAD_CTRL)
125
126#define MX25_PAD_BCLK__BCLK IOMUX_PAD(0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL)
127#define MX25_PAD_BCLK__GPIO_4_4 IOMUX_PAD(0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL)
128
129#define MX25_PAD_RW__RW IOMUX_PAD(0x278, 0x06c, 0x10, 0, 0, NO_PAD_CTRL)
130#define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(0x278, 0x06c, 0x14, 0x474, 0, NO_PAD_CTRL)
131#define MX25_PAD_RW__GPIO_3_25 IOMUX_PAD(0x278, 0x06c, 0x15, 0, 0, NO_PAD_CTRL)
132
133#define MX25_PAD_NFWE_B__NFWE_B IOMUX_PAD(0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL)
134#define MX25_PAD_NFWE_B__GPIO_3_26 IOMUX_PAD(0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL)
135
136#define MX25_PAD_NFRE_B__NFRE_B IOMUX_PAD(0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL)
137#define MX25_PAD_NFRE_B__GPIO_3_27 IOMUX_PAD(0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL)
138
139#define MX25_PAD_NFALE__NFALE IOMUX_PAD(0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL)
140#define MX25_PAD_NFALE__GPIO_3_28 IOMUX_PAD(0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL)
141
142#define MX25_PAD_NFCLE__NFCLE IOMUX_PAD(0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL)
143#define MX25_PAD_NFCLE__GPIO_3_29 IOMUX_PAD(0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL)
144
145#define MX25_PAD_NFWP_B__NFWP_B IOMUX_PAD(0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL)
146#define MX25_PAD_NFWP_B__GPIO_3_30 IOMUX_PAD(0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL)
147
148#define MX25_PAD_NFRB__NFRB IOMUX_PAD(0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PKE)
149#define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL)
150
151#define MX25_PAD_D15__D15 IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL)
152#define MX25_PAD_D15__LD16 IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, NO_PAD_CTRL)
153#define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL)
154
155#define MX25_PAD_D14__D14 IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL)
156#define MX25_PAD_D14__LD17 IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, NO_PAD_CTRL)
157#define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL)
158
159#define MX25_PAD_D13__D13 IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL)
160#define MX25_PAD_D13__LD18 IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, NO_PAD_CTRL)
161#define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL)
162
163#define MX25_PAD_D12__D12 IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL)
164#define MX25_PAD_D12__GPIO_4_8 IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL)
165
166#define MX25_PAD_D11__D11 IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL)
167#define MX25_PAD_D11__GPIO_4_9 IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL)
168
169#define MX25_PAD_D10__D10 IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL)
170#define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL)
171#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP)
172
173#define MX25_PAD_D9__D9 IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL)
174#define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL)
175#define MX25_PAD_D9__USBH2_PWR IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE)
176
177#define MX25_PAD_D8__D8 IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL)
178#define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL)
179#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP)
180
181#define MX25_PAD_D7__D7 IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL)
182#define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL)
183
184#define MX25_PAD_D6__D6 IOMUX_PAD(0x2a4, 0x0ac, 0x00, 0, 0, NO_PAD_CTRL)
185#define MX25_PAD_D6__GPIO_4_14 IOMUX_PAD(0x2a4, 0x0ac, 0x05, 0, 0, NO_PAD_CTRL)
186
187#define MX25_PAD_D5__D5 IOMUX_PAD(0x2a8, 0x0b0, 0x00, 0, 0, NO_PAD_CTRL)
188#define MX25_PAD_D5__GPIO_4_15 IOMUX_PAD(0x2a8, 0x0b0, 0x05, 0, 0, NO_PAD_CTRL)
189
190#define MX25_PAD_D4__D4 IOMUX_PAD(0x2ac, 0x0b4, 0x00, 0, 0, NO_PAD_CTRL)
191#define MX25_PAD_D4__GPIO_4_16 IOMUX_PAD(0x2ac, 0x0b4, 0x05, 0, 0, NO_PAD_CTRL)
192
193#define MX25_PAD_D3__D3 IOMUX_PAD(0x2b0, 0x0b8, 0x00, 0, 0, NO_PAD_CTRL)
194#define MX25_PAD_D3__GPIO_4_17 IOMUX_PAD(0x2b0, 0x0b8, 0x05, 0, 0, NO_PAD_CTRL)
195
196#define MX25_PAD_D2__D2 IOMUX_PAD(0x2b4, 0x0bc, 0x00, 0, 0, NO_PAD_CTRL)
197#define MX25_PAD_D2__GPIO_4_18 IOMUX_PAD(0x2b4, 0x0bc, 0x05, 0, 0, NO_PAD_CTRL)
198
199#define MX25_PAD_D1__D1 IOMUX_PAD(0x2b8, 0x0c0, 0x00, 0, 0, NO_PAD_CTRL)
200#define MX25_PAD_D1__GPIO_4_19 IOMUX_PAD(0x2b8, 0x0c0, 0x05, 0, 0, NO_PAD_CTRL)
201
202#define MX25_PAD_D0__D0 IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL)
203#define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL)
204
205#define MX25_PAD_LD0__LD0 IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, NO_PAD_CTRL)
206#define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL)
207#define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL)
208
209#define MX25_PAD_LD1__LD1 IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, NO_PAD_CTRL)
210#define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL)
211#define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL)
212
213#define MX25_PAD_LD2__LD2 IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, NO_PAD_CTRL)
214#define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL)
215
216#define MX25_PAD_LD3__LD3 IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, NO_PAD_CTRL)
217#define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL)
218
219#define MX25_PAD_LD4__LD4 IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, NO_PAD_CTRL)
220#define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL)
221
222#define MX25_PAD_LD5__LD5 IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, NO_PAD_CTRL)
223#define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL)
224
225#define MX25_PAD_LD6__LD6 IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, NO_PAD_CTRL)
226#define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL)
227
228#define MX25_PAD_LD7__LD7 IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, NO_PAD_CTRL)
229#define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL)
230
231#define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL)
232#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTL)
233
234#define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL)
235#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTL)
236
237#define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL)
238#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTL)
239
240#define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL)
241#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTL)
242
243#define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL)
244#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTL)
245
246#define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL)
247#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTL)
248
249#define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL)
250#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTL)
251
252#define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL)
253#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTL)
254
255#define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL)
256#define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL)
257
258#define MX25_PAD_VSYNC__VSYNC IOMUX_PAD(0x304, 0x10c, 0x10, 0, 0, NO_PAD_CTRL)
259#define MX25_PAD_VSYNC__GPIO_1_23 IOMUX_PAD(0x304, 0x10c, 0x15, 0, 0, NO_PAD_CTRL)
260
261#define MX25_PAD_LSCLK__LSCLK IOMUX_PAD(0x308, 0x110, 0x10, 0, 0, NO_PAD_CTRL)
262#define MX25_PAD_LSCLK__GPIO_1_24 IOMUX_PAD(0x308, 0x110, 0x15, 0, 0, NO_PAD_CTRL)
263
264#define MX25_PAD_OE_ACD__OE_ACD IOMUX_PAD(0x30c, 0x114, 0x10, 0, 0, NO_PAD_CTRL)
265#define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL)
266
267#define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL)
268#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTL)
269
270#define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL)
271#define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL)
272#define MX25_PAD_PWM__USBH2_OC IOMUX_PAD(0x314, 0x11c, 0x16, 0x580, 1, PAD_CTL_PUS_100K_UP)
273
274#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL)
275#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL)
276#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL)
277
278#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL)
279#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL)
280
281#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL)
282#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL)
283#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL)
284
285#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL)
286#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL)
287
288#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL)
289#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL)
290
291#define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0, NO_PAD_CTRL)
292#define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0, NO_PAD_CTRL)
293
294#define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(0x330, 0x138, 0x10, 0, 0, NO_PAD_CTRL)
295#define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(0x330, 0x138, 0x15, 0, 0, NO_PAD_CTRL)
296
297#define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0, NO_PAD_CTRL)
298#define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0, NO_PAD_CTRL)
299
300#define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(0x338, 0x140, 0x10, 0, 0, NO_PAD_CTRL)
301#define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(0x338, 0x140, 0x15, 0, 0, NO_PAD_CTRL)
302
303#define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0, NO_PAD_CTRL)
304#define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0, NO_PAD_CTRL)
305
306#define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(0x340, 0x148, 0x10, 0, 0, NO_PAD_CTRL)
307#define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(0x340, 0x148, 0x15, 0, 0, NO_PAD_CTRL)
308
309#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(0x344, 0x14c, 0x10, 0, 0, NO_PAD_CTRL)
310#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(0x344, 0x14c, 0x15, 0, 0, NO_PAD_CTRL)
311
312#define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x348, 0x150, 0x10, 0, 0, NO_PAD_CTRL)
313#define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(0x348, 0x150, 0x15, 0, 0, NO_PAD_CTRL)
314
315#define MX25_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x34c, 0x154, 0x10, 0, 0, NO_PAD_CTRL)
316#define MX25_PAD_I2C1_DAT__GPIO_1_13 IOMUX_PAD(0x34c, 0x154, 0x15, 0, 0, NO_PAD_CTRL)
317
318#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x350, 0x158, 0x10, 0, 0, NO_PAD_CTRL)
319#define MX25_PAD_CSPI1_MOSI__GPIO_1_14 IOMUX_PAD(0x350, 0x158, 0x15, 0, 0, NO_PAD_CTRL)
320
321#define MX25_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x354, 0x15c, 0x10, 0, 0, NO_PAD_CTRL)
322#define MX25_PAD_CSPI1_MISO__GPIO_1_15 IOMUX_PAD(0x354, 0x15c, 0x15, 0, 0, NO_PAD_CTRL)
323
324#define MX25_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x358, 0x160, 0x10, 0, 0, NO_PAD_CTRL)
325#define MX25_PAD_CSPI1_SS0__GPIO_1_16 IOMUX_PAD(0x358, 0x160, 0x15, 0, 0, NO_PAD_CTRL)
326
327#define MX25_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x35c, 0x164, 0x10, 0, 0, NO_PAD_CTRL)
328#define MX25_PAD_CSPI1_SS1__GPIO_1_17 IOMUX_PAD(0x35c, 0x164, 0x15, 0, 0, NO_PAD_CTRL)
329
330#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x360, 0x168, 0x10, 0, 0, NO_PAD_CTRL)
331#define MX25_PAD_CSPI1_SCLK__GPIO_1_18 IOMUX_PAD(0x360, 0x168, 0x15, 0, 0, NO_PAD_CTRL)
332
333#define MX25_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PKE)
334#define MX25_PAD_CSPI1_RDY__GPIO_2_22 IOMUX_PAD(0x364, 0x16c, 0x15, 0, 0, NO_PAD_CTRL)
335
336#define MX25_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x368, 0x170, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN)
337#define MX25_PAD_UART1_RXD__GPIO_4_22 IOMUX_PAD(0x368, 0x170, 0x15, 0, 0, NO_PAD_CTRL)
338
339#define MX25_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x36c, 0x174, 0x10, 0, 0, NO_PAD_CTRL)
340#define MX25_PAD_UART1_TXD__GPIO_4_23 IOMUX_PAD(0x36c, 0x174, 0x15, 0, 0, NO_PAD_CTRL)
341
342#define MX25_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x370, 0x178, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
343#define MX25_PAD_UART1_RTS__CSI_D0 IOMUX_PAD(0x370, 0x178, 0x11, 0x488, 1, NO_PAD_CTRL)
344#define MX25_PAD_UART1_RTS__GPIO_4_24 IOMUX_PAD(0x370, 0x178, 0x15, 0, 0, NO_PAD_CTRL)
345
346#define MX25_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
347#define MX25_PAD_UART1_CTS__CSI_D1 IOMUX_PAD(0x374, 0x17c, 0x11, 0x48c, 1, NO_PAD_CTRL)
348#define MX25_PAD_UART1_CTS__GPIO_4_25 IOMUX_PAD(0x374, 0x17c, 0x15, 0, 0, NO_PAD_CTRL)
349
350#define MX25_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x378, 0x180, 0x10, 0, 0, NO_PAD_CTRL)
351#define MX25_PAD_UART2_RXD__GPIO_4_26 IOMUX_PAD(0x378, 0x180, 0x15, 0, 0, NO_PAD_CTRL)
352
353#define MX25_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x37c, 0x184, 0x10, 0, 0, NO_PAD_CTRL)
354#define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL)
355
356#define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL)
357#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTL)
358#define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL)
359
360#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTL)
361#define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL)
362#define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL)
363
364#define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
365#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTL)
366#define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL)
367
368#define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
369#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTL)
370#define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL)
371
372#define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
373#define MX25_PAD_SD1_DATA0__GPIO_2_25 IOMUX_PAD(0x390, 0x198, 0x15, 0, 0, NO_PAD_CTRL)
374
375#define MX25_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
376#define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(0x394, 0x19c, 0x13, 0x478, 0, NO_PAD_CTRL)
377#define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL)
378
379#define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
380#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTL)
381#define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL)
382
383#define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
384#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTL)
385#define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
386
387#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE)
388#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL)
389
390#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PKE)
391#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL)
392
393#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PKE)
394#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL)
395#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL)
396
397#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PKE)
398#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL)
399#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL)
400
401#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
402#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL)
403
404#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
405#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL)
406
407#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
408#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL)
409
410#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
411#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
412
413#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTL)
414#define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL)
415#define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL)
416
417#define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP)
418#define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL)
419#define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL)
420
421#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTL)
422#define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL)
423
424#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTL)
425#define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL)
426#define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL)
427
428#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTL)
429#define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL)
430
431#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
432#define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL)
433
434#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
435#define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL)
436
437#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
438#define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP)
439#define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL)
440
441#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN)
442#define MX25_PAD_FEC_TX_CLK__GPIO_3_13 IOMUX_PAD(0x3e0, 0x1e8, 0x15, 0, 0, NO_PAD_CTRL)
443
444#define MX25_PAD_RTCK__RTCK IOMUX_PAD(0x3e4, 0x1ec, 0x10, 0, 0, NO_PAD_CTRL)
445#define MX25_PAD_RTCK__OWIRE IOMUX_PAD(0x3e4, 0x1ec, 0x11, 0, 0, NO_PAD_CTRL)
446#define MX25_PAD_RTCK__GPIO_3_14 IOMUX_PAD(0x3e4, 0x1ec, 0x15, 0, 0, NO_PAD_CTRL)
447
448#define MX25_PAD_DE_B__DE_B IOMUX_PAD(0x3ec, 0x1f0, 0x10, 0, 0, NO_PAD_CTRL)
449#define MX25_PAD_DE_B__GPIO_2_20 IOMUX_PAD(0x3ec, 0x1f0, 0x15, 0, 0, NO_PAD_CTRL)
450
451#define MX25_PAD_TDO__TDO IOMUX_PAD(0x3e8, 0x000, 0x00, 0, 0, NO_PAD_CTRL)
452
453#define MX25_PAD_GPIO_A__GPIO_A IOMUX_PAD(0x3f0, 0x1f4, 0x10, 0, 0, NO_PAD_CTRL)
454#define MX25_PAD_GPIO_A__CAN1_TX IOMUX_PAD(0x3f0, 0x1f4, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
455#define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE)
456
457#define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL)
458#define MX25_PAD_GPIO_B__CAN1_RX IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K)
459#define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP)
460
461#define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL)
462#define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
463
464#define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
465#define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
466
467#define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
468#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
469
470#define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
471#define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL)
472
473#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL)
474#define MX25_PAD_EXT_ARMCLK__GPIO_3_15 IOMUX_PAD(0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL)
475
476#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL)
477#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 IOMUX_PAD(0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL)
478
479#define MX25_PAD_VSTBY_REQ__VSTBY_REQ IOMUX_PAD(0x408, 0x214, 0x10, 0, 0, NO_PAD_CTRL)
480#define MX25_PAD_VSTBY_REQ__AUD7_TXFS IOMUX_PAD(0x408, 0x214, 0x14, 0, 0, NO_PAD_CTRL)
481#define MX25_PAD_VSTBY_REQ__GPIO_3_17 IOMUX_PAD(0x408, 0x214, 0x15, 0, 0, NO_PAD_CTRL)
482#define MX25_PAD_VSTBY_ACK__VSTBY_ACK IOMUX_PAD(0x40c, 0x218, 0x10, 0, 0, NO_PAD_CTRL)
483#define MX25_PAD_VSTBY_ACK__GPIO_3_18 IOMUX_PAD(0x40c, 0x218, 0x15, 0, 0, NO_PAD_CTRL)
484
485#define MX25_PAD_POWER_FAIL__POWER_FAIL IOMUX_PAD(0x410, 0x21c, 0x10, 0, 0, NO_PAD_CTRL)
486#define MX25_PAD_POWER_FAIL__AUD7_RXD IOMUX_PAD(0x410, 0x21c, 0x14, 0x478, 1, NO_PAD_CTRL)
487#define MX25_PAD_POWER_FAIL__GPIO_3_19 IOMUX_PAD(0x410, 0x21c, 0x15, 0, 0, NO_PAD_CTRL)
488
489#define MX25_PAD_CLKO__CLKO IOMUX_PAD(0x414, 0x220, 0x10, 0, 0, NO_PAD_CTRL)
490#define MX25_PAD_CLKO__GPIO_2_21 IOMUX_PAD(0x414, 0x220, 0x15, 0, 0, NO_PAD_CTRL)
491
492#define MX25_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL)
493#define MX25_PAD_BOOT_MODE0__GPIO_4_30 IOMUX_PAD(0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL)
494#define MX25_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL)
495#define MX25_PAD_BOOT_MODE1__GPIO_4_31 IOMUX_PAD(0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL)
496
497#define MX25_PAD_CTL_GRP_DVS_MISC IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL)
498#define MX25_PAD_CTL_GRP_DSE_FEC IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL)
499#define MX25_PAD_CTL_GRP_DVS_JTAG IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL)
500#define MX25_PAD_CTL_GRP_DSE_NFC IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL)
501#define MX25_PAD_CTL_GRP_DSE_CSI IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL)
502#define MX25_PAD_CTL_GRP_DSE_WEIM IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL)
503#define MX25_PAD_CTL_GRP_DSE_DDR IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL)
504#define MX25_PAD_CTL_GRP_DVS_CRM IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL)
505#define MX25_PAD_CTL_GRP_DSE_KPP IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL)
506#define MX25_PAD_CTL_GRP_DSE_SDHC1 IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL)
507#define MX25_PAD_CTL_GRP_DSE_LCD IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL)
508#define MX25_PAD_CTL_GRP_DSE_UART IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL)
509#define MX25_PAD_CTL_GRP_DVS_NFC IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL)
510#define MX25_PAD_CTL_GRP_DVS_CSI IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL)
511#define MX25_PAD_CTL_GRP_DSE_CSPI1 IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL)
512#define MX25_PAD_CTL_GRP_DDRTYPE IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL)
513#define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL)
514#define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL)
515
516#endif // __ASSEMBLY__
517#endif // __IOMUX_MX25_H__
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index 2eb182f73876..446f86763816 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -635,6 +635,19 @@ enum iomux_pins {
635#define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC) 635#define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC)
636#define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC) 636#define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC)
637#define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC) 637#define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC)
638#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
639#define MX31_PIN_CSPI1_MISO__USBH1_RXDP IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
640#define MX31_PIN_CSPI1_SS0__USBH1_TXDM IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1)
641#define MX31_PIN_CSPI1_SS1__USBH1_TXDP IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1)
642#define MX31_PIN_CSPI1_SS2__USBH1_RCV IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1)
643#define MX31_PIN_CSPI1_SCLK__USBH1_OEB IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
644#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
645#define MX31_PIN_USBH2_DATA0__USBH2_DATA0 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
646#define MX31_PIN_USBH2_DATA1__USBH2_DATA1 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
647#define MX31_PIN_USBH2_CLK__USBH2_CLK IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
648#define MX31_PIN_USBH2_DIR__USBH2_DIR IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
649#define MX31_PIN_USBH2_NXT__USBH2_NXT IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
650#define MX31_PIN_USBH2_STP__USBH2_STP IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
638#define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO) 651#define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO)
639#define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) 652#define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
640#define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC) 653#define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC)
@@ -669,6 +682,18 @@ enum iomux_pins {
669#define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO) 682#define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO)
670#define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO) 683#define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)
671#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO) 684#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
685#define MX31_PIN_GPIO1_0__GPIO1_0 IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO)
686#define MX31_PIN_SVEN0__GPIO2_0 IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO)
687#define MX31_PIN_STX0__GPIO2_1 IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO)
688#define MX31_PIN_SRX0__GPIO2_2 IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO)
689#define MX31_PIN_SIMPD0__GPIO2_3 IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO)
690#define MX31_PIN_DTR_DCE1__GPIO2_8 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO)
691#define MX31_PIN_DSR_DCE1__GPIO2_9 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO)
692#define MX31_PIN_RI_DCE1__GPIO2_10 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO)
693#define MX31_PIN_DCD_DCE1__GPIO2_11 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO)
694#define MX31_PIN_STXD5__GPIO1_21 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
695#define MX31_PIN_SRXD5__GPIO1_22 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
696
672 697
673/*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0 698/*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
674 * cspi1_ss1*/ 699 * cspi1_ss1*/
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
new file mode 100644
index 000000000000..9f13061192c8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
@@ -0,0 +1,287 @@
1/*
2 * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
4 * Copyright (C) 2009 by Dmitriy Taychenachev <dimichxp@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __MACH_IOMUX_MXC91231_H__
22#define __MACH_IOMUX_MXC91231_H__
23
24/*
25 * various IOMUX output functions
26 */
27
28#define IOMUX_OCONFIG_GPIO (0 << 4) /* used as GPIO */
29#define IOMUX_OCONFIG_FUNC (1 << 4) /* used as function */
30#define IOMUX_OCONFIG_ALT1 (2 << 4) /* used as alternate function 1 */
31#define IOMUX_OCONFIG_ALT2 (3 << 4) /* used as alternate function 2 */
32#define IOMUX_OCONFIG_ALT3 (4 << 4) /* used as alternate function 3 */
33#define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */
34#define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */
35#define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */
36#define IOMUX_ICONFIG_NONE 0 /* not configured for input */
37#define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */
38#define IOMUX_ICONFIG_FUNC 2 /* used as function */
39#define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */
40#define IOMUX_ICONFIG_ALT2 8 /* used as alternate function 2 */
41
42#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO)
43#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC)
44#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1)
45#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2)
46
47/*
48 * setups a single pin:
49 * - reserves the pin so that it is not claimed by another driver
50 * - setups the iomux according to the configuration
51 * - if the pin is configured as a GPIO, we claim it throug kernel gpiolib
52 */
53int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label);
54/*
55 * setups mutliple pins
56 * convenient way to call the above function with tables
57 */
58int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
59 const char *label);
60
61/*
62 * releases a single pin:
63 * - make it available for a future use by another driver
64 * - frees the GPIO if the pin was configured as GPIO
65 * - DOES NOT reconfigure the IOMUX in its reset state
66 */
67void mxc_iomux_release_pin(const unsigned int pin_mode);
68/*
69 * releases multiple pins
70 * convenvient way to call the above function with tables
71 */
72void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);
73
74#define MUX_SIDE_AP (0)
75#define MUX_SIDE_SP (1)
76
77#define MUX_SIDE_SHIFT (26)
78#define MUX_SIDE_MASK (0x1 << MUX_SIDE_SHIFT)
79
80#define MUX_GPIO_PORT_SHIFT (23)
81#define MUX_GPIO_PORT_MASK (0x7 << MUX_GPIO_PORT_SHIFT)
82
83#define MUX_GPIO_PIN_SHIFT (20)
84#define MUX_GPIO_PIN_MASK (0x1f << MUX_GPIO_PIN_SHIFT)
85
86#define MUX_REG_SHIFT (15)
87#define MUX_REG_MASK (0x1f << MUX_REG_SHIFT)
88
89#define MUX_FIELD_SHIFT (13)
90#define MUX_FIELD_MASK (0x3 << MUX_FIELD_SHIFT)
91
92#define MUX_PADGRP_SHIFT (8)
93#define MUX_PADGRP_MASK (0x1f << MUX_PADGRP_SHIFT)
94
95#define MUX_PIN_MASK (0xffffff << 8)
96
97#define GPIO_PORT_MAX (3)
98
99#define IOMUX_PIN(side, gport, gpin, ctlreg, ctlfield, padgrp) \
100 (((side) << MUX_SIDE_SHIFT) | \
101 (gport << MUX_GPIO_PORT_SHIFT) | \
102 ((gpin) << MUX_GPIO_PIN_SHIFT) | \
103 ((ctlreg) << MUX_REG_SHIFT) | \
104 ((ctlfield) << MUX_FIELD_SHIFT) | \
105 ((padgrp) << MUX_PADGRP_SHIFT))
106
107#define MUX_MODE_OUT_SHIFT (4)
108#define MUX_MODE_IN_SHIFT (0)
109#define MUX_MODE_SHIFT (0)
110#define MUX_MODE_MASK (0xff << MUX_MODE_SHIFT)
111
112#define IOMUX_MODE(pin, mode) \
113 (pin | (mode << MUX_MODE_SHIFT))
114
115enum iomux_pins {
116 /* AP Side pins */
117 MXC91231_PIN_AP_CLE = IOMUX_PIN(0, 0, 0, 0, 0, 24),
118 MXC91231_PIN_AP_ALE = IOMUX_PIN(0, 0, 1, 0, 1, 24),
119 MXC91231_PIN_AP_CE_B = IOMUX_PIN(0, 0, 2, 0, 2, 24),
120 MXC91231_PIN_AP_RE_B = IOMUX_PIN(0, 0, 3, 0, 3, 24),
121 MXC91231_PIN_AP_WE_B = IOMUX_PIN(0, 0, 4, 1, 0, 24),
122 MXC91231_PIN_AP_WP_B = IOMUX_PIN(0, 0, 5, 1, 1, 24),
123 MXC91231_PIN_AP_BSY_B = IOMUX_PIN(0, 0, 6, 1, 2, 24),
124 MXC91231_PIN_AP_U1_TXD = IOMUX_PIN(0, 0, 7, 1, 3, 28),
125 MXC91231_PIN_AP_U1_RXD = IOMUX_PIN(0, 0, 8, 2, 0, 28),
126 MXC91231_PIN_AP_U1_RTS_B = IOMUX_PIN(0, 0, 9, 2, 1, 28),
127 MXC91231_PIN_AP_U1_CTS_B = IOMUX_PIN(0, 0, 10, 2, 2, 28),
128 MXC91231_PIN_AP_AD1_TXD = IOMUX_PIN(0, 0, 11, 2, 3, 9),
129 MXC91231_PIN_AP_AD1_RXD = IOMUX_PIN(0, 0, 12, 3, 0, 9),
130 MXC91231_PIN_AP_AD1_TXC = IOMUX_PIN(0, 0, 13, 3, 1, 9),
131 MXC91231_PIN_AP_AD1_TXFS = IOMUX_PIN(0, 0, 14, 3, 2, 9),
132 MXC91231_PIN_AP_AD2_TXD = IOMUX_PIN(0, 0, 15, 3, 3, 9),
133 MXC91231_PIN_AP_AD2_RXD = IOMUX_PIN(0, 0, 16, 4, 0, 9),
134 MXC91231_PIN_AP_AD2_TXC = IOMUX_PIN(0, 0, 17, 4, 1, 9),
135 MXC91231_PIN_AP_AD2_TXFS = IOMUX_PIN(0, 0, 18, 4, 2, 9),
136 MXC91231_PIN_AP_OWDAT = IOMUX_PIN(0, 0, 19, 4, 3, 28),
137 MXC91231_PIN_AP_IPU_LD17 = IOMUX_PIN(0, 0, 20, 5, 0, 28),
138 MXC91231_PIN_AP_IPU_D3_VSYNC = IOMUX_PIN(0, 0, 21, 5, 1, 28),
139 MXC91231_PIN_AP_IPU_D3_HSYNC = IOMUX_PIN(0, 0, 22, 5, 2, 28),
140 MXC91231_PIN_AP_IPU_D3_CLK = IOMUX_PIN(0, 0, 23, 5, 3, 28),
141 MXC91231_PIN_AP_IPU_D3_DRDY = IOMUX_PIN(0, 0, 24, 6, 0, 28),
142 MXC91231_PIN_AP_IPU_D3_CONTR = IOMUX_PIN(0, 0, 25, 6, 1, 28),
143 MXC91231_PIN_AP_IPU_D0_CS = IOMUX_PIN(0, 0, 26, 6, 2, 28),
144 MXC91231_PIN_AP_IPU_LD16 = IOMUX_PIN(0, 0, 27, 6, 3, 28),
145 MXC91231_PIN_AP_IPU_D2_CS = IOMUX_PIN(0, 0, 28, 7, 0, 28),
146 MXC91231_PIN_AP_IPU_PAR_RS = IOMUX_PIN(0, 0, 29, 7, 1, 28),
147 MXC91231_PIN_AP_IPU_D3_PS = IOMUX_PIN(0, 0, 30, 7, 2, 28),
148 MXC91231_PIN_AP_IPU_D3_CLS = IOMUX_PIN(0, 0, 31, 7, 3, 28),
149 MXC91231_PIN_AP_IPU_RD = IOMUX_PIN(0, 1, 0, 8, 0, 28),
150 MXC91231_PIN_AP_IPU_WR = IOMUX_PIN(0, 1, 1, 8, 1, 28),
151 MXC91231_PIN_AP_IPU_LD0 = IOMUX_PIN(0, 7, 0, 8, 2, 28),
152 MXC91231_PIN_AP_IPU_LD1 = IOMUX_PIN(0, 7, 0, 8, 3, 28),
153 MXC91231_PIN_AP_IPU_LD2 = IOMUX_PIN(0, 7, 0, 9, 0, 28),
154 MXC91231_PIN_AP_IPU_LD3 = IOMUX_PIN(0, 1, 2, 9, 1, 28),
155 MXC91231_PIN_AP_IPU_LD4 = IOMUX_PIN(0, 1, 3, 9, 2, 28),
156 MXC91231_PIN_AP_IPU_LD5 = IOMUX_PIN(0, 1, 4, 9, 3, 28),
157 MXC91231_PIN_AP_IPU_LD6 = IOMUX_PIN(0, 1, 5, 10, 0, 28),
158 MXC91231_PIN_AP_IPU_LD7 = IOMUX_PIN(0, 1, 6, 10, 1, 28),
159 MXC91231_PIN_AP_IPU_LD8 = IOMUX_PIN(0, 1, 7, 10, 2, 28),
160 MXC91231_PIN_AP_IPU_LD9 = IOMUX_PIN(0, 1, 8, 10, 3, 28),
161 MXC91231_PIN_AP_IPU_LD10 = IOMUX_PIN(0, 1, 9, 11, 0, 28),
162 MXC91231_PIN_AP_IPU_LD11 = IOMUX_PIN(0, 1, 10, 11, 1, 28),
163 MXC91231_PIN_AP_IPU_LD12 = IOMUX_PIN(0, 1, 11, 11, 2, 28),
164 MXC91231_PIN_AP_IPU_LD13 = IOMUX_PIN(0, 1, 12, 11, 3, 28),
165 MXC91231_PIN_AP_IPU_LD14 = IOMUX_PIN(0, 1, 13, 12, 0, 28),
166 MXC91231_PIN_AP_IPU_LD15 = IOMUX_PIN(0, 1, 14, 12, 1, 28),
167 MXC91231_PIN_AP_KPROW4 = IOMUX_PIN(0, 7, 0, 12, 2, 10),
168 MXC91231_PIN_AP_KPROW5 = IOMUX_PIN(0, 1, 16, 12, 3, 10),
169 MXC91231_PIN_AP_GPIO_AP_B17 = IOMUX_PIN(0, 1, 17, 13, 0, 10),
170 MXC91231_PIN_AP_GPIO_AP_B18 = IOMUX_PIN(0, 1, 18, 13, 1, 10),
171 MXC91231_PIN_AP_KPCOL3 = IOMUX_PIN(0, 1, 19, 13, 2, 11),
172 MXC91231_PIN_AP_KPCOL4 = IOMUX_PIN(0, 1, 20, 13, 3, 11),
173 MXC91231_PIN_AP_KPCOL5 = IOMUX_PIN(0, 1, 21, 14, 0, 11),
174 MXC91231_PIN_AP_GPIO_AP_B22 = IOMUX_PIN(0, 1, 22, 14, 1, 11),
175 MXC91231_PIN_AP_GPIO_AP_B23 = IOMUX_PIN(0, 1, 23, 14, 2, 11),
176 MXC91231_PIN_AP_CSI_D0 = IOMUX_PIN(0, 1, 24, 14, 3, 21),
177 MXC91231_PIN_AP_CSI_D1 = IOMUX_PIN(0, 1, 25, 15, 0, 21),
178 MXC91231_PIN_AP_CSI_D2 = IOMUX_PIN(0, 1, 26, 15, 1, 21),
179 MXC91231_PIN_AP_CSI_D3 = IOMUX_PIN(0, 1, 27, 15, 2, 21),
180 MXC91231_PIN_AP_CSI_D4 = IOMUX_PIN(0, 1, 28, 15, 3, 21),
181 MXC91231_PIN_AP_CSI_D5 = IOMUX_PIN(0, 1, 29, 16, 0, 21),
182 MXC91231_PIN_AP_CSI_D6 = IOMUX_PIN(0, 1, 30, 16, 1, 21),
183 MXC91231_PIN_AP_CSI_D7 = IOMUX_PIN(0, 1, 31, 16, 2, 21),
184 MXC91231_PIN_AP_CSI_D8 = IOMUX_PIN(0, 2, 0, 16, 3, 21),
185 MXC91231_PIN_AP_CSI_D9 = IOMUX_PIN(0, 2, 1, 17, 0, 21),
186 MXC91231_PIN_AP_CSI_MCLK = IOMUX_PIN(0, 2, 2, 17, 1, 21),
187 MXC91231_PIN_AP_CSI_VSYNC = IOMUX_PIN(0, 2, 3, 17, 2, 21),
188 MXC91231_PIN_AP_CSI_HSYNC = IOMUX_PIN(0, 2, 4, 17, 3, 21),
189 MXC91231_PIN_AP_CSI_PIXCLK = IOMUX_PIN(0, 2, 5, 18, 0, 21),
190 MXC91231_PIN_AP_I2CLK = IOMUX_PIN(0, 2, 6, 18, 1, 12),
191 MXC91231_PIN_AP_I2DAT = IOMUX_PIN(0, 2, 7, 18, 2, 12),
192 MXC91231_PIN_AP_GPIO_AP_C8 = IOMUX_PIN(0, 2, 8, 18, 3, 9),
193 MXC91231_PIN_AP_GPIO_AP_C9 = IOMUX_PIN(0, 2, 9, 19, 0, 9),
194 MXC91231_PIN_AP_GPIO_AP_C10 = IOMUX_PIN(0, 2, 10, 19, 1, 9),
195 MXC91231_PIN_AP_GPIO_AP_C11 = IOMUX_PIN(0, 2, 11, 19, 2, 9),
196 MXC91231_PIN_AP_GPIO_AP_C12 = IOMUX_PIN(0, 2, 12, 19, 3, 9),
197 MXC91231_PIN_AP_GPIO_AP_C13 = IOMUX_PIN(0, 2, 13, 20, 0, 28),
198 MXC91231_PIN_AP_GPIO_AP_C14 = IOMUX_PIN(0, 2, 14, 20, 1, 28),
199 MXC91231_PIN_AP_GPIO_AP_C15 = IOMUX_PIN(0, 2, 15, 20, 2, 9),
200 MXC91231_PIN_AP_GPIO_AP_C16 = IOMUX_PIN(0, 2, 16, 20, 3, 9),
201 MXC91231_PIN_AP_GPIO_AP_C17 = IOMUX_PIN(0, 2, 17, 21, 0, 9),
202 MXC91231_PIN_AP_ED_INT0 = IOMUX_PIN(0, 2, 18, 21, 1, 22),
203 MXC91231_PIN_AP_ED_INT1 = IOMUX_PIN(0, 2, 19, 21, 2, 22),
204 MXC91231_PIN_AP_ED_INT2 = IOMUX_PIN(0, 2, 20, 21, 3, 22),
205 MXC91231_PIN_AP_ED_INT3 = IOMUX_PIN(0, 2, 21, 22, 0, 22),
206 MXC91231_PIN_AP_ED_INT4 = IOMUX_PIN(0, 2, 22, 22, 1, 23),
207 MXC91231_PIN_AP_ED_INT5 = IOMUX_PIN(0, 2, 23, 22, 2, 23),
208 MXC91231_PIN_AP_ED_INT6 = IOMUX_PIN(0, 2, 24, 22, 3, 23),
209 MXC91231_PIN_AP_ED_INT7 = IOMUX_PIN(0, 2, 25, 23, 0, 23),
210 MXC91231_PIN_AP_U2_DSR_B = IOMUX_PIN(0, 2, 26, 23, 1, 28),
211 MXC91231_PIN_AP_U2_RI_B = IOMUX_PIN(0, 2, 27, 23, 2, 28),
212 MXC91231_PIN_AP_U2_CTS_B = IOMUX_PIN(0, 2, 28, 23, 3, 28),
213 MXC91231_PIN_AP_U2_DTR_B = IOMUX_PIN(0, 2, 29, 24, 0, 28),
214 MXC91231_PIN_AP_KPROW0 = IOMUX_PIN(0, 7, 0, 24, 1, 10),
215 MXC91231_PIN_AP_KPROW1 = IOMUX_PIN(0, 1, 15, 24, 2, 10),
216 MXC91231_PIN_AP_KPROW2 = IOMUX_PIN(0, 7, 0, 24, 3, 10),
217 MXC91231_PIN_AP_KPROW3 = IOMUX_PIN(0, 7, 0, 25, 0, 10),
218 MXC91231_PIN_AP_KPCOL0 = IOMUX_PIN(0, 7, 0, 25, 1, 11),
219 MXC91231_PIN_AP_KPCOL1 = IOMUX_PIN(0, 7, 0, 25, 2, 11),
220 MXC91231_PIN_AP_KPCOL2 = IOMUX_PIN(0, 7, 0, 25, 3, 11),
221
222 /* Shared pins */
223 MXC91231_PIN_SP_U3_TXD = IOMUX_PIN(1, 3, 0, 0, 0, 28),
224 MXC91231_PIN_SP_U3_RXD = IOMUX_PIN(1, 3, 1, 0, 1, 28),
225 MXC91231_PIN_SP_U3_RTS_B = IOMUX_PIN(1, 3, 2, 0, 2, 28),
226 MXC91231_PIN_SP_U3_CTS_B = IOMUX_PIN(1, 3, 3, 0, 3, 28),
227 MXC91231_PIN_SP_USB_TXOE_B = IOMUX_PIN(1, 3, 4, 1, 0, 28),
228 MXC91231_PIN_SP_USB_DAT_VP = IOMUX_PIN(1, 3, 5, 1, 1, 28),
229 MXC91231_PIN_SP_USB_SE0_VM = IOMUX_PIN(1, 3, 6, 1, 2, 28),
230 MXC91231_PIN_SP_USB_RXD = IOMUX_PIN(1, 3, 7, 1, 3, 28),
231 MXC91231_PIN_SP_UH2_TXOE_B = IOMUX_PIN(1, 3, 8, 2, 0, 28),
232 MXC91231_PIN_SP_UH2_SPEED = IOMUX_PIN(1, 3, 9, 2, 1, 28),
233 MXC91231_PIN_SP_UH2_SUSPEN = IOMUX_PIN(1, 3, 10, 2, 2, 28),
234 MXC91231_PIN_SP_UH2_TXDP = IOMUX_PIN(1, 3, 11, 2, 3, 28),
235 MXC91231_PIN_SP_UH2_RXDP = IOMUX_PIN(1, 3, 12, 3, 0, 28),
236 MXC91231_PIN_SP_UH2_RXDM = IOMUX_PIN(1, 3, 13, 3, 1, 28),
237 MXC91231_PIN_SP_UH2_OVR = IOMUX_PIN(1, 3, 14, 3, 2, 28),
238 MXC91231_PIN_SP_UH2_PWR = IOMUX_PIN(1, 3, 15, 3, 3, 28),
239 MXC91231_PIN_SP_SD1_DAT0 = IOMUX_PIN(1, 3, 16, 4, 0, 25),
240 MXC91231_PIN_SP_SD1_DAT1 = IOMUX_PIN(1, 3, 17, 4, 1, 25),
241 MXC91231_PIN_SP_SD1_DAT2 = IOMUX_PIN(1, 3, 18, 4, 2, 25),
242 MXC91231_PIN_SP_SD1_DAT3 = IOMUX_PIN(1, 3, 19, 4, 3, 25),
243 MXC91231_PIN_SP_SD1_CMD = IOMUX_PIN(1, 3, 20, 5, 0, 25),
244 MXC91231_PIN_SP_SD1_CLK = IOMUX_PIN(1, 3, 21, 5, 1, 25),
245 MXC91231_PIN_SP_SD2_DAT0 = IOMUX_PIN(1, 3, 22, 5, 2, 26),
246 MXC91231_PIN_SP_SD2_DAT1 = IOMUX_PIN(1, 3, 23, 5, 3, 26),
247 MXC91231_PIN_SP_SD2_DAT2 = IOMUX_PIN(1, 3, 24, 6, 0, 26),
248 MXC91231_PIN_SP_SD2_DAT3 = IOMUX_PIN(1, 3, 25, 6, 1, 26),
249 MXC91231_PIN_SP_GPIO_SP_A26 = IOMUX_PIN(1, 3, 26, 6, 2, 28),
250 MXC91231_PIN_SP_SPI1_CLK = IOMUX_PIN(1, 3, 27, 6, 3, 13),
251 MXC91231_PIN_SP_SPI1_MOSI = IOMUX_PIN(1, 3, 28, 7, 0, 13),
252 MXC91231_PIN_SP_SPI1_MISO = IOMUX_PIN(1, 3, 29, 7, 1, 13),
253 MXC91231_PIN_SP_SPI1_SS0 = IOMUX_PIN(1, 3, 30, 7, 2, 13),
254 MXC91231_PIN_SP_SPI1_SS1 = IOMUX_PIN(1, 3, 31, 7, 3, 13),
255 MXC91231_PIN_SP_SD2_CMD = IOMUX_PIN(1, 7, 0, 8, 0, 26),
256 MXC91231_PIN_SP_SD2_CLK = IOMUX_PIN(1, 7, 0, 8, 1, 26),
257 MXC91231_PIN_SP_SIM1_RST_B = IOMUX_PIN(1, 2, 30, 8, 2, 28),
258 MXC91231_PIN_SP_SIM1_SVEN = IOMUX_PIN(1, 7, 0, 8, 3, 28),
259 MXC91231_PIN_SP_SIM1_CLK = IOMUX_PIN(1, 7, 0, 9, 0, 28),
260 MXC91231_PIN_SP_SIM1_TRXD = IOMUX_PIN(1, 7, 0, 9, 1, 28),
261 MXC91231_PIN_SP_SIM1_PD = IOMUX_PIN(1, 2, 31, 9, 2, 28),
262 MXC91231_PIN_SP_UH2_TXDM = IOMUX_PIN(1, 7, 0, 9, 3, 28),
263 MXC91231_PIN_SP_UH2_RXD = IOMUX_PIN(1, 7, 0, 10, 0, 28),
264};
265
266#define PIN_AP_MAX (104)
267#define PIN_SP_MAX (41)
268
269#define PIN_MAX (PIN_AP_MAX + PIN_SP_MAX)
270
271/*
272 * Convenience values for use with mxc_iomux_mode()
273 *
274 * Format here is MXC91231_PIN_(pin name)__(function)
275 */
276
277#define MXC91231_PIN_SP_USB_DAT_VP__USB_DAT_VP \
278 IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_FUNC)
279#define MXC91231_PIN_SP_USB_SE0_VM__USB_SE0_VM \
280 IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_FUNC)
281#define MXC91231_PIN_SP_USB_DAT_VP__RXD2 \
282 IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_ALT1)
283#define MXC91231_PIN_SP_USB_SE0_VM__TXD2 \
284 IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_ALT1)
285
286
287#endif /* __MACH_IOMUX_MXC91231_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
index 7cd84547658f..a0fa40265468 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -68,28 +68,24 @@ struct pad_desc {
68/* 68/*
69 * Use to set PAD control 69 * Use to set PAD control
70 */ 70 */
71#define PAD_CTL_DRIVE_VOLTAGE_3_3_V 0
72#define PAD_CTL_DRIVE_VOLTAGE_1_8_V 1
73 71
74#define PAD_CTL_NO_HYSTERESIS 0 72#define PAD_CTL_DVS (1 << 13)
75#define PAD_CTL_HYSTERESIS 1 73#define PAD_CTL_HYS (1 << 8)
76 74
77#define PAD_CTL_PULL_DISABLED 0x0 75#define PAD_CTL_PKE (1 << 7)
78#define PAD_CTL_PULL_KEEPER 0xa 76#define PAD_CTL_PUE (1 << 6)
79#define PAD_CTL_PULL_DOWN_100K 0xc 77#define PAD_CTL_PUS_100K_DOWN (0 << 4)
80#define PAD_CTL_PULL_UP_47K 0xd 78#define PAD_CTL_PUS_47K_UP (1 << 4)
81#define PAD_CTL_PULL_UP_100K 0xe 79#define PAD_CTL_PUS_100K_UP (2 << 4)
82#define PAD_CTL_PULL_UP_22K 0xf 80#define PAD_CTL_PUS_22K_UP (3 << 4)
83 81
84#define PAD_CTL_OUTPUT_CMOS 0 82#define PAD_CTL_ODE (1 << 3)
85#define PAD_CTL_OUTPUT_OPEN_DRAIN 1
86 83
87#define PAD_CTL_DRIVE_STRENGTH_NORM 0 84#define PAD_CTL_DSE_STANDARD (0 << 1)
88#define PAD_CTL_DRIVE_STRENGTH_HIGH 1 85#define PAD_CTL_DSE_HIGH (1 << 1)
89#define PAD_CTL_DRIVE_STRENGTH_MAX 2 86#define PAD_CTL_DSE_MAX (2 << 1)
90 87
91#define PAD_CTL_SLEW_RATE_SLOW 0 88#define PAD_CTL_SRE_FAST (1 << 0)
92#define PAD_CTL_SLEW_RATE_FAST 1
93 89
94/* 90/*
95 * setups a single pad: 91 * setups a single pad:
@@ -117,5 +113,10 @@ void mxc_iomux_v3_release_pad(struct pad_desc *pad);
117 */ 113 */
118void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count); 114void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count);
119 115
116/*
117 * Initialise the iomux controller
118 */
119void mxc_iomux_v3_init(void __iomem *iomux_v3_base);
120
120#endif /* __MACH_IOMUX_V3_H__*/ 121#endif /* __MACH_IOMUX_V3_H__*/
121 122
diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h
index 171f8adc1109..6d49f8ae3259 100644
--- a/arch/arm/plat-mxc/include/mach/iomux.h
+++ b/arch/arm/plat-mxc/include/mach/iomux.h
@@ -49,6 +49,9 @@
49#ifdef CONFIG_ARCH_MX2 49#ifdef CONFIG_ARCH_MX2
50# define GPIO_PORT_MAX 5 50# define GPIO_PORT_MAX 5
51#endif 51#endif
52#ifdef CONFIG_ARCH_MX25
53# define GPIO_PORT_MAX 3
54#endif
52 55
53#ifndef GPIO_PORT_MAX 56#ifndef GPIO_PORT_MAX
54# error "GPIO config port count unknown!" 57# error "GPIO config port count unknown!"
@@ -107,6 +110,9 @@
107#include <mach/iomux-mx27.h> 110#include <mach/iomux-mx27.h>
108#endif 111#endif
109#endif 112#endif
113#ifdef CONFIG_ARCH_MX25
114#include <mach/iomux-mx25.h>
115#endif
110 116
111 117
112/* decode irq number to use with IMR(x), ISR(x) and friends */ 118/* decode irq number to use with IMR(x), ISR(x) and friends */
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 518a36504b88..ead9d592168d 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -24,6 +24,10 @@
24#define MXC_GPIO_IRQS (32 * 6) 24#define MXC_GPIO_IRQS (32 * 6)
25#elif defined CONFIG_ARCH_MX3 25#elif defined CONFIG_ARCH_MX3
26#define MXC_GPIO_IRQS (32 * 3) 26#define MXC_GPIO_IRQS (32 * 3)
27#elif defined CONFIG_ARCH_MX25
28#define MXC_GPIO_IRQS (32 * 4)
29#elif defined CONFIG_ARCH_MXC91231
30#define MXC_GPIO_IRQS (32 * 4)
27#endif 31#endif
28 32
29/* 33/*
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 6065e00176ed..d3afafdcc0e5 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -22,6 +22,10 @@
22#endif 22#endif
23#elif defined CONFIG_ARCH_MX3 23#elif defined CONFIG_ARCH_MX3
24#define PHYS_OFFSET UL(0x80000000) 24#define PHYS_OFFSET UL(0x80000000)
25#elif defined CONFIG_ARCH_MX25
26#define PHYS_OFFSET UL(0x80000000)
27#elif defined CONFIG_ARCH_MXC91231
28#define PHYS_OFFSET UL(0x90000000)
25#endif 29#endif
26 30
27#if defined(CONFIG_MX1_VIDEO) 31#if defined(CONFIG_MX1_VIDEO)
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h
index 1000bf330bcd..1b2890a5c452 100644
--- a/arch/arm/plat-mxc/include/mach/mx1.h
+++ b/arch/arm/plat-mxc/include/mach/mx1.h
@@ -12,10 +12,6 @@
12#ifndef __ASM_ARCH_MXC_MX1_H__ 12#ifndef __ASM_ARCH_MXC_MX1_H__
13#define __ASM_ARCH_MXC_MX1_H__ 13#define __ASM_ARCH_MXC_MX1_H__
14 14
15#ifndef __ASM_ARCH_MXC_HARDWARE_H__
16#error "Do not include directly."
17#endif
18
19#include <mach/vmalloc.h> 15#include <mach/vmalloc.h>
20 16
21/* 17/*
@@ -138,20 +134,6 @@
138#define GPIO_INT_PORTD 62 134#define GPIO_INT_PORTD 62
139#define WDT_INT 63 135#define WDT_INT 63
140 136
141/* gpio and gpio based interrupt handling */
142#define GPIO_DR 0x1C
143#define GPIO_GDIR 0x00
144#define GPIO_PSR 0x24
145#define GPIO_ICR1 0x28
146#define GPIO_ICR2 0x2C
147#define GPIO_IMR 0x30
148#define GPIO_ISR 0x34
149#define GPIO_INT_LOW_LEV 0x3
150#define GPIO_INT_HIGH_LEV 0x2
151#define GPIO_INT_RISE_EDGE 0x0
152#define GPIO_INT_FALL_EDGE 0x1
153#define GPIO_INT_NONE 0x4
154
155/* DMA */ 137/* DMA */
156#define DMA_REQ_UART3_T 2 138#define DMA_REQ_UART3_T 2
157#define DMA_REQ_UART3_R 3 139#define DMA_REQ_UART3_R 3
@@ -179,8 +161,4 @@
179#define DMA_REQ_UART1_T 30 161#define DMA_REQ_UART1_T 30
180#define DMA_REQ_UART1_R 31 162#define DMA_REQ_UART1_R 31
181 163
182/* mandatory for CONFIG_DEBUG_LL */
183#define MXC_LL_UART_PADDR UART1_BASE_ADDR
184#define MXC_LL_UART_VADDR IO_ADDRESS(UART1_BASE_ADDR)
185
186#endif /* __ASM_ARCH_MXC_MX1_H__ */ 164#endif /* __ASM_ARCH_MXC_MX1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
index 8b070a041a99..21112c695ec5 100644
--- a/arch/arm/plat-mxc/include/mach/mx21.h
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -25,11 +25,6 @@
25#ifndef __ASM_ARCH_MXC_MX21_H__ 25#ifndef __ASM_ARCH_MXC_MX21_H__
26#define __ASM_ARCH_MXC_MX21_H__ 26#define __ASM_ARCH_MXC_MX21_H__
27 27
28#ifndef __ASM_ARCH_MXC_HARDWARE_H__
29#error "Do not include directly."
30#endif
31
32
33/* Memory regions and CS */ 28/* Memory regions and CS */
34#define SDRAM_BASE_ADDR 0xC0000000 29#define SDRAM_BASE_ADDR 0xC0000000
35#define CSD1_BASE_ADDR 0xC4000000 30#define CSD1_BASE_ADDR 0xC4000000
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
new file mode 100644
index 000000000000..ec64bd9a8ab1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -0,0 +1,44 @@
1#ifndef __MACH_MX25_H__
2#define __MACH_MX25_H__
3
4#define MX25_AIPS1_BASE_ADDR 0x43F00000
5#define MX25_AIPS1_BASE_ADDR_VIRT 0xFC000000
6#define MX25_AIPS1_SIZE SZ_1M
7#define MX25_AIPS2_BASE_ADDR 0x53F00000
8#define MX25_AIPS2_BASE_ADDR_VIRT 0xFC200000
9#define MX25_AIPS2_SIZE SZ_1M
10#define MX25_AVIC_BASE_ADDR 0x68000000
11#define MX25_AVIC_BASE_ADDR_VIRT 0xFC400000
12#define MX25_AVIC_SIZE SZ_1M
13
14#define MX25_IOMUXC_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xac000)
15
16#define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000)
17#define MX25_GPT1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x90000)
18#define MX25_WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xdc000)
19
20#define MX25_GPIO1_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xcc000)
21#define MX25_GPIO2_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xd0000)
22#define MX25_GPIO3_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xa4000)
23#define MX25_GPIO4_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0x9c000)
24
25#define MX25_AIPS1_IO_ADDRESS(x) \
26 (((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
27#define MX25_AIPS2_IO_ADDRESS(x) \
28 (((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT)
29#define MX25_AVIC_IO_ADDRESS(x) \
30 (((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT)
31
32#define __in_range(addr, name) ((addr) >= name##_BASE_ADDR && (addr) < name##_BASE_ADDR + name##_SIZE)
33
34#define MX25_IO_ADDRESS(x) \
35 (void __force __iomem *) \
36 (__in_range(x, MX25_AIPS1) ? MX25_AIPS1_IO_ADDRESS(x) : \
37 __in_range(x, MX25_AIPS2) ? MX25_AIPS2_IO_ADDRESS(x) : \
38 __in_range(x, MX25_AVIC) ? MX25_AVIC_IO_ADDRESS(x) : \
39 0xDEADBEEF)
40
41#define UART1_BASE_ADDR 0x43f90000
42#define UART2_BASE_ADDR 0x43f94000
43
44#endif /* __MACH_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index 6e93f2c0b7bb..dc3ad9aa952a 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -24,10 +24,6 @@
24#ifndef __ASM_ARCH_MXC_MX27_H__ 24#ifndef __ASM_ARCH_MXC_MX27_H__
25#define __ASM_ARCH_MXC_MX27_H__ 25#define __ASM_ARCH_MXC_MX27_H__
26 26
27#ifndef __ASM_ARCH_MXC_HARDWARE_H__
28#error "Do not include directly."
29#endif
30
31/* IRAM */ 27/* IRAM */
32#define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */ 28#define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */
33 29
@@ -120,7 +116,4 @@ extern int mx27_revision(void);
120 116
121/* Mandatory defines used globally */ 117/* Mandatory defines used globally */
122 118
123/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */
124#define ARCH_NR_GPIOS (192 + 16)
125
126#endif /* __ASM_ARCH_MXC_MX27_H__ */ 119#endif /* __ASM_ARCH_MXC_MX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h
index fc40d3ab8c5b..db5d921e0fe6 100644
--- a/arch/arm/plat-mxc/include/mach/mx2x.h
+++ b/arch/arm/plat-mxc/include/mach/mx2x.h
@@ -23,10 +23,6 @@
23#ifndef __ASM_ARCH_MXC_MX2x_H__ 23#ifndef __ASM_ARCH_MXC_MX2x_H__
24#define __ASM_ARCH_MXC_MX2x_H__ 24#define __ASM_ARCH_MXC_MX2x_H__
25 25
26#ifndef __ASM_ARCH_MXC_HARDWARE_H__
27#error "Do not include directly."
28#endif
29
30/* The following addresses are common between i.MX21 and i.MX27 */ 26/* The following addresses are common between i.MX21 and i.MX27 */
31 27
32/* Register offests */ 28/* Register offests */
@@ -154,20 +150,6 @@
154#define MXC_INT_GPIO 8 150#define MXC_INT_GPIO 8
155#define MXC_INT_CSPI3 6 151#define MXC_INT_CSPI3 6
156 152
157/* gpio and gpio based interrupt handling */
158#define GPIO_DR 0x1C
159#define GPIO_GDIR 0x00
160#define GPIO_PSR 0x24
161#define GPIO_ICR1 0x28
162#define GPIO_ICR2 0x2C
163#define GPIO_IMR 0x30
164#define GPIO_ISR 0x34
165#define GPIO_INT_LOW_LEV 0x3
166#define GPIO_INT_HIGH_LEV 0x2
167#define GPIO_INT_RISE_EDGE 0x0
168#define GPIO_INT_FALL_EDGE 0x1
169#define GPIO_INT_NONE 0x4
170
171/* fixed DMA request numbers */ 153/* fixed DMA request numbers */
172#define DMA_REQ_CSI_RX 31 154#define DMA_REQ_CSI_RX 31
173#define DMA_REQ_CSI_STAT 30 155#define DMA_REQ_CSI_STAT 30
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index 0b06941b6139..14ac0dcc82f4 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -4,7 +4,7 @@
4#define MX31_IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */ 4#define MX31_IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */
5#define MX31_IRAM_SIZE SZ_16K 5#define MX31_IRAM_SIZE SZ_16K
6 6
7#define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) 7#define MX31_OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000)
8#define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) 8#define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000)
9#define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) 9#define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000)
10#define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000) 10#define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000)
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index 6465fefb42e3..ab4cfec6c8ab 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -5,6 +5,7 @@
5#define MX35_IRAM_SIZE SZ_128K 5#define MX35_IRAM_SIZE SZ_128K
6 6
7#define MXC_FEC_BASE_ADDR 0x50038000 7#define MXC_FEC_BASE_ADDR 0x50038000
8#define MX35_OTG_BASE_ADDR 0x53ff4000
8#define MX35_NFC_BASE_ADDR 0xBB000000 9#define MX35_NFC_BASE_ADDR 0xBB000000
9 10
10/* 11/*
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h
index b559a4bb5769..009f4440276b 100644
--- a/arch/arm/plat-mxc/include/mach/mx3x.h
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -11,10 +11,6 @@
11#ifndef __ASM_ARCH_MXC_MX31_H__ 11#ifndef __ASM_ARCH_MXC_MX31_H__
12#define __ASM_ARCH_MXC_MX31_H__ 12#define __ASM_ARCH_MXC_MX31_H__
13 13
14#ifndef __ASM_ARCH_MXC_HARDWARE_H__
15#error "Do not include directly."
16#endif
17
18/* 14/*
19 * MX31 memory map: 15 * MX31 memory map:
20 * 16 *
@@ -263,25 +259,8 @@
263#define SYSTEM_REV_MIN CHIP_REV_1_0 259#define SYSTEM_REV_MIN CHIP_REV_1_0
264#define SYSTEM_REV_NUM 3 260#define SYSTEM_REV_NUM 3
265 261
266/* gpio and gpio based interrupt handling */
267#define GPIO_DR 0x00
268#define GPIO_GDIR 0x04
269#define GPIO_PSR 0x08
270#define GPIO_ICR1 0x0C
271#define GPIO_ICR2 0x10
272#define GPIO_IMR 0x14
273#define GPIO_ISR 0x18
274#define GPIO_INT_LOW_LEV 0x0
275#define GPIO_INT_HIGH_LEV 0x1
276#define GPIO_INT_RISE_EDGE 0x2
277#define GPIO_INT_FALL_EDGE 0x3
278#define GPIO_INT_NONE 0x4
279
280/* Mandatory defines used globally */ 262/* Mandatory defines used globally */
281 263
282/* this CPU supports up to 96 GPIOs */
283#define ARCH_NR_GPIOS 96
284
285#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) 264#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
286 265
287extern unsigned int system_rev; 266extern unsigned int system_rev;
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 5fa2a07f4eaf..51990536b845 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -26,9 +26,11 @@
26 26
27#define MXC_CPU_MX1 1 27#define MXC_CPU_MX1 1
28#define MXC_CPU_MX21 21 28#define MXC_CPU_MX21 21
29#define MXC_CPU_MX25 25
29#define MXC_CPU_MX27 27 30#define MXC_CPU_MX27 27
30#define MXC_CPU_MX31 31 31#define MXC_CPU_MX31 31
31#define MXC_CPU_MX35 35 32#define MXC_CPU_MX35 35
33#define MXC_CPU_MXC91231 91231
32 34
33#ifndef __ASSEMBLY__ 35#ifndef __ASSEMBLY__
34extern unsigned int __mxc_cpu_type; 36extern unsigned int __mxc_cpu_type;
@@ -58,6 +60,18 @@ extern unsigned int __mxc_cpu_type;
58# define cpu_is_mx21() (0) 60# define cpu_is_mx21() (0)
59#endif 61#endif
60 62
63#ifdef CONFIG_ARCH_MX25
64# ifdef mxc_cpu_type
65# undef mxc_cpu_type
66# define mxc_cpu_type __mxc_cpu_type
67# else
68# define mxc_cpu_type MXC_CPU_MX25
69# endif
70# define cpu_is_mx25() (mxc_cpu_type == MXC_CPU_MX25)
71#else
72# define cpu_is_mx25() (0)
73#endif
74
61#ifdef CONFIG_MACH_MX27 75#ifdef CONFIG_MACH_MX27
62# ifdef mxc_cpu_type 76# ifdef mxc_cpu_type
63# undef mxc_cpu_type 77# undef mxc_cpu_type
@@ -94,13 +108,25 @@ extern unsigned int __mxc_cpu_type;
94# define cpu_is_mx35() (0) 108# define cpu_is_mx35() (0)
95#endif 109#endif
96 110
111#ifdef CONFIG_ARCH_MXC91231
112# ifdef mxc_cpu_type
113# undef mxc_cpu_type
114# define mxc_cpu_type __mxc_cpu_type
115# else
116# define mxc_cpu_type MXC_CPU_MXC91231
117# endif
118# define cpu_is_mxc91231() (mxc_cpu_type == MXC_CPU_MXC91231)
119#else
120# define cpu_is_mxc91231() (0)
121#endif
122
97#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) 123#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
98#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10) 124#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10)
99#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4) 125#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4)
100#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8) 126#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
101#endif 127#endif
102 128
103#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) 129#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
104#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) 130#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
105 131
106#endif /* __ASM_ARCH_MXC_H__ */ 132#endif /* __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h
new file mode 100644
index 000000000000..81484d1ef232
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc91231.h
@@ -0,0 +1,315 @@
1/*
2 * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
3 * - Platform specific register memory map
4 *
5 * Copyright 2005-2007 Motorola, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef __MACH_MXC91231_H__
22#define __MACH_MXC91231_H__
23
24/*
25 * L2CC
26 */
27#define MXC91231_L2CC_BASE_ADDR 0x30000000
28#define MXC91231_L2CC_BASE_ADDR_VIRT 0xF9000000
29#define MXC91231_L2CC_SIZE SZ_64K
30
31/*
32 * AIPS 1
33 */
34#define MXC91231_AIPS1_BASE_ADDR 0x43F00000
35#define MXC91231_AIPS1_BASE_ADDR_VIRT 0xFC000000
36#define MXC91231_AIPS1_SIZE SZ_1M
37
38#define MXC91231_AIPS1_CTRL_BASE_ADDR MXC91231_AIPS1_BASE_ADDR
39#define MXC91231_MAX_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x04000)
40#define MXC91231_EVTMON_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x08000)
41#define MXC91231_CLKCTL_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x0C000)
42#define MXC91231_ETB_SLOT4_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x10000)
43#define MXC91231_ETB_SLOT5_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x14000)
44#define MXC91231_ECT_CTIO_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x18000)
45#define MXC91231_I2C_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x80000)
46#define MXC91231_MU_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x88000)
47#define MXC91231_UART1_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x90000)
48#define MXC91231_UART2_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x94000)
49#define MXC91231_DSM_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x98000)
50#define MXC91231_OWIRE_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x9C000)
51#define MXC91231_SSI1_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xA0000)
52#define MXC91231_KPP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xA8000)
53#define MXC91231_IOMUX_AP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xAC000)
54#define MXC91231_CTI_AP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xB8000)
55
56/*
57 * AIPS 2
58 */
59#define MXC91231_AIPS2_BASE_ADDR 0x53F00000
60#define MXC91231_AIPS2_BASE_ADDR_VIRT 0xFC100000
61#define MXC91231_AIPS2_SIZE SZ_1M
62
63#define MXC91231_GEMK_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x8C000)
64#define MXC91231_GPT1_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x90000)
65#define MXC91231_EPIT1_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x94000)
66#define MXC91231_SCC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xAC000)
67#define MXC91231_RNGA_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xB0000)
68#define MXC91231_IPU_CTRL_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC0000)
69#define MXC91231_AUDMUX_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC4000)
70#define MXC91231_EDIO_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC8000)
71#define MXC91231_GPIO1_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xCC000)
72#define MXC91231_GPIO2_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD0000)
73#define MXC91231_SDMA_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD4000)
74#define MXC91231_RTC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD8000)
75#define MXC91231_WDOG1_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xDC000)
76#define MXC91231_PWM_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE0000)
77#define MXC91231_GPIO3_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE4000)
78#define MXC91231_WDOG2_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE8000)
79#define MXC91231_RTIC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xEC000)
80#define MXC91231_LPMC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xF0000)
81
82/*
83 * SPBA global module 0
84 */
85#define MXC91231_SPBA0_BASE_ADDR 0x50000000
86#define MXC91231_SPBA0_BASE_ADDR_VIRT 0xFC200000
87#define MXC91231_SPBA0_SIZE SZ_1M
88
89#define MXC91231_MMC_SDHC1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x04000)
90#define MXC91231_MMC_SDHC2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x08000)
91#define MXC91231_UART3_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x0C000)
92#define MXC91231_CSPI2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x10000)
93#define MXC91231_SSI2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x14000)
94#define MXC91231_SIM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x18000)
95#define MXC91231_IIM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x1C000)
96#define MXC91231_CTI_SDMA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x20000)
97#define MXC91231_USBOTG_CTRL_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x24000)
98#define MXC91231_USBOTG_DATA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x28000)
99#define MXC91231_CSPI1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x30000)
100#define MXC91231_SPBA_CTRL_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x3C000)
101#define MXC91231_IOMUX_COM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x40000)
102#define MXC91231_CRM_COM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x44000)
103#define MXC91231_CRM_AP_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x48000)
104#define MXC91231_PLL0_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x4C000)
105#define MXC91231_PLL1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x50000)
106#define MXC91231_PLL2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x54000)
107#define MXC91231_GPIO4_SH_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x58000)
108#define MXC91231_HAC_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x5C000)
109#define MXC91231_SAHARA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x5C000)
110#define MXC91231_PLL3_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x60000)
111
112/*
113 * SPBA global module 1
114 */
115#define MXC91231_SPBA1_BASE_ADDR 0x52000000
116#define MXC91231_SPBA1_BASE_ADDR_VIRT 0xFC300000
117#define MXC91231_SPBA1_SIZE SZ_1M
118
119#define MXC91231_MQSPI_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x34000)
120#define MXC91231_EL1T_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x38000)
121
122/*!
123 * Defines for SPBA modules
124 */
125#define MXC91231_SPBA_SDHC1 0x04
126#define MXC91231_SPBA_SDHC2 0x08
127#define MXC91231_SPBA_UART3 0x0C
128#define MXC91231_SPBA_CSPI2 0x10
129#define MXC91231_SPBA_SSI2 0x14
130#define MXC91231_SPBA_SIM 0x18
131#define MXC91231_SPBA_IIM 0x1C
132#define MXC91231_SPBA_CTI_SDMA 0x20
133#define MXC91231_SPBA_USBOTG_CTRL_REGS 0x24
134#define MXC91231_SPBA_USBOTG_DATA_REGS 0x28
135#define MXC91231_SPBA_CSPI1 0x30
136#define MXC91231_SPBA_MQSPI 0x34
137#define MXC91231_SPBA_EL1T 0x38
138#define MXC91231_SPBA_IOMUX 0x40
139#define MXC91231_SPBA_CRM_COM 0x44
140#define MXC91231_SPBA_CRM_AP 0x48
141#define MXC91231_SPBA_PLL0 0x4C
142#define MXC91231_SPBA_PLL1 0x50
143#define MXC91231_SPBA_PLL2 0x54
144#define MXC91231_SPBA_GPIO4 0x58
145#define MXC91231_SPBA_SAHARA 0x5C
146
147/*
148 * ROMP and AVIC
149 */
150#define MXC91231_ROMP_BASE_ADDR 0x60000000
151#define MXC91231_ROMP_BASE_ADDR_VIRT 0xFC400000
152#define MXC91231_ROMP_SIZE SZ_64K
153
154#define MXC91231_AVIC_BASE_ADDR 0x68000000
155#define MXC91231_AVIC_BASE_ADDR_VIRT 0xFC410000
156#define MXC91231_AVIC_SIZE SZ_64K
157
158/*
159 * NAND, SDRAM, WEIM, M3IF, EMI controllers
160 */
161#define MXC91231_X_MEMC_BASE_ADDR 0xB8000000
162#define MXC91231_X_MEMC_BASE_ADDR_VIRT 0xFC420000
163#define MXC91231_X_MEMC_SIZE SZ_64K
164
165#define MXC91231_NFC_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x0000)
166#define MXC91231_ESDCTL_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x1000)
167#define MXC91231_WEIM_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x2000)
168#define MXC91231_M3IF_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x3000)
169#define MXC91231_EMI_CTL_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x4000)
170
171/*
172 * Memory regions and CS
173 * CPLD is connected on CS4
174 * CS5 is TP1021 or it is not connected
175 * */
176#define MXC91231_FB_RAM_BASE_ADDR 0x78000000
177#define MXC91231_FB_RAM_SIZE SZ_256K
178#define MXC91231_CSD0_BASE_ADDR 0x80000000
179#define MXC91231_CSD1_BASE_ADDR 0x90000000
180#define MXC91231_CS0_BASE_ADDR 0xA0000000
181#define MXC91231_CS1_BASE_ADDR 0xA8000000
182#define MXC91231_CS2_BASE_ADDR 0xB0000000
183#define MXC91231_CS3_BASE_ADDR 0xB2000000
184#define MXC91231_CS4_BASE_ADDR 0xB4000000
185#define MXC91231_CS5_BASE_ADDR 0xB6000000
186
187/* Is given address belongs to the specified memory region? */
188#define ADDRESS_IN_REGION(addr, start, size) \
189 (((addr) >= (start)) && ((addr) < (start)+(size)))
190
191/* Is given address belongs to the specified named `module'? */
192#define MXC91231_IS_MODULE(addr, module) \
193 ADDRESS_IN_REGION(addr, MXC91231_ ## module ## _BASE_ADDR, \
194 MXC91231_ ## module ## _SIZE)
195/*
196 * This macro defines the physical to virtual address mapping for all the
197 * peripheral modules. It is used by passing in the physical address as x
198 * and returning the virtual address. If the physical address is not mapped,
199 * it returns 0xDEADBEEF
200 */
201
202#define MXC91231_IO_ADDRESS(x) \
203 (void __iomem *) \
204 (MXC91231_IS_MODULE(x, L2CC) ? MXC91231_L2CC_IO_ADDRESS(x) : \
205 MXC91231_IS_MODULE(x, AIPS1) ? MXC91231_AIPS1_IO_ADDRESS(x) : \
206 MXC91231_IS_MODULE(x, AIPS2) ? MXC91231_AIPS2_IO_ADDRESS(x) : \
207 MXC91231_IS_MODULE(x, SPBA0) ? MXC91231_SPBA0_IO_ADDRESS(x) : \
208 MXC91231_IS_MODULE(x, SPBA1) ? MXC91231_SPBA1_IO_ADDRESS(x) : \
209 MXC91231_IS_MODULE(x, ROMP) ? MXC91231_ROMP_IO_ADDRESS(x) : \
210 MXC91231_IS_MODULE(x, AVIC) ? MXC91231_AVIC_IO_ADDRESS(x) : \
211 MXC91231_IS_MODULE(x, X_MEMC) ? MXC91231_X_MEMC_IO_ADDRESS(x) : \
212 0xDEADBEEF)
213
214
215/*
216 * define the address mapping macros: in physical address order
217 */
218#define MXC91231_L2CC_IO_ADDRESS(x) \
219 (((x) - MXC91231_L2CC_BASE_ADDR) + MXC91231_L2CC_BASE_ADDR_VIRT)
220
221#define MXC91231_AIPS1_IO_ADDRESS(x) \
222 (((x) - MXC91231_AIPS1_BASE_ADDR) + MXC91231_AIPS1_BASE_ADDR_VIRT)
223
224#define MXC91231_SPBA0_IO_ADDRESS(x) \
225 (((x) - MXC91231_SPBA0_BASE_ADDR) + MXC91231_SPBA0_BASE_ADDR_VIRT)
226
227#define MXC91231_SPBA1_IO_ADDRESS(x) \
228 (((x) - MXC91231_SPBA1_BASE_ADDR) + MXC91231_SPBA1_BASE_ADDR_VIRT)
229
230#define MXC91231_AIPS2_IO_ADDRESS(x) \
231 (((x) - MXC91231_AIPS2_BASE_ADDR) + MXC91231_AIPS2_BASE_ADDR_VIRT)
232
233#define MXC91231_ROMP_IO_ADDRESS(x) \
234 (((x) - MXC91231_ROMP_BASE_ADDR) + MXC91231_ROMP_BASE_ADDR_VIRT)
235
236#define MXC91231_AVIC_IO_ADDRESS(x) \
237 (((x) - MXC91231_AVIC_BASE_ADDR) + MXC91231_AVIC_BASE_ADDR_VIRT)
238
239#define MXC91231_X_MEMC_IO_ADDRESS(x) \
240 (((x) - MXC91231_X_MEMC_BASE_ADDR) + MXC91231_X_MEMC_BASE_ADDR_VIRT)
241
242/*
243 * Interrupt numbers
244 */
245#define MXC91231_INT_GPIO3 0
246#define MXC91231_INT_EL1T_CI 1
247#define MXC91231_INT_EL1T_RFCI 2
248#define MXC91231_INT_EL1T_RFI 3
249#define MXC91231_INT_EL1T_MCU 4
250#define MXC91231_INT_EL1T_IPI 5
251#define MXC91231_INT_MU_GEN 6
252#define MXC91231_INT_GPIO4 7
253#define MXC91231_INT_MMC_SDHC2 8
254#define MXC91231_INT_MMC_SDHC1 9
255#define MXC91231_INT_I2C 10
256#define MXC91231_INT_SSI2 11
257#define MXC91231_INT_SSI1 12
258#define MXC91231_INT_CSPI2 13
259#define MXC91231_INT_CSPI1 14
260#define MXC91231_INT_RTIC 15
261#define MXC91231_INT_SAHARA 15
262#define MXC91231_INT_HAC 15
263#define MXC91231_INT_UART3_RX 16
264#define MXC91231_INT_UART3_TX 17
265#define MXC91231_INT_UART3_MINT 18
266#define MXC91231_INT_ECT 19
267#define MXC91231_INT_SIM_IPB 20
268#define MXC91231_INT_SIM_DATA 21
269#define MXC91231_INT_RNGA 22
270#define MXC91231_INT_DSM_AP 23
271#define MXC91231_INT_KPP 24
272#define MXC91231_INT_RTC 25
273#define MXC91231_INT_PWM 26
274#define MXC91231_INT_GEMK_AP 27
275#define MXC91231_INT_EPIT 28
276#define MXC91231_INT_GPT 29
277#define MXC91231_INT_UART2_RX 30
278#define MXC91231_INT_UART2_TX 31
279#define MXC91231_INT_UART2_MINT 32
280#define MXC91231_INT_NANDFC 33
281#define MXC91231_INT_SDMA 34
282#define MXC91231_INT_USB_WAKEUP 35
283#define MXC91231_INT_USB_SOF 36
284#define MXC91231_INT_PMU_EVTMON 37
285#define MXC91231_INT_USB_FUNC 38
286#define MXC91231_INT_USB_DMA 39
287#define MXC91231_INT_USB_CTRL 40
288#define MXC91231_INT_IPU_ERR 41
289#define MXC91231_INT_IPU_SYN 42
290#define MXC91231_INT_UART1_RX 43
291#define MXC91231_INT_UART1_TX 44
292#define MXC91231_INT_UART1_MINT 45
293#define MXC91231_INT_IIM 46
294#define MXC91231_INT_MU_RX_OR 47
295#define MXC91231_INT_MU_TX_OR 48
296#define MXC91231_INT_SCC_SCM 49
297#define MXC91231_INT_SCC_SMN 50
298#define MXC91231_INT_GPIO2 51
299#define MXC91231_INT_GPIO1 52
300#define MXC91231_INT_MQSPI1 53
301#define MXC91231_INT_MQSPI2 54
302#define MXC91231_INT_WDOG2 55
303#define MXC91231_INT_EXT_INT7 56
304#define MXC91231_INT_EXT_INT6 57
305#define MXC91231_INT_EXT_INT5 58
306#define MXC91231_INT_EXT_INT4 59
307#define MXC91231_INT_EXT_INT3 60
308#define MXC91231_INT_EXT_INT2 61
309#define MXC91231_INT_EXT_INT1 62
310#define MXC91231_INT_EXT_INT0 63
311
312#define MXC91231_MAX_INT_LINES 63
313#define MXC91231_MAX_EXT_LINES 8
314
315#endif /* __MACH_MXC91231_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index e56241af870e..ef00199568de 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -21,8 +21,18 @@
21#ifndef __ASM_ARCH_MXC_SYSTEM_H__ 21#ifndef __ASM_ARCH_MXC_SYSTEM_H__
22#define __ASM_ARCH_MXC_SYSTEM_H__ 22#define __ASM_ARCH_MXC_SYSTEM_H__
23 23
24#include <mach/hardware.h>
25#include <mach/common.h>
26
24static inline void arch_idle(void) 27static inline void arch_idle(void)
25{ 28{
29#ifdef CONFIG_ARCH_MXC91231
30 if (cpu_is_mxc91231()) {
31 /* Need this to set DSM low-power mode */
32 mxc91231_prepare_idle();
33 }
34#endif
35
26 cpu_do_idle(); 36 cpu_do_idle();
27} 37}
28 38
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
index 07b4a73c9d2f..527a6c24788e 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/arch/arm/plat-mxc/include/mach/timex.h
@@ -26,6 +26,10 @@
26#define CLOCK_TICK_RATE 13300000 26#define CLOCK_TICK_RATE 13300000
27#elif defined CONFIG_ARCH_MX3 27#elif defined CONFIG_ARCH_MX3
28#define CLOCK_TICK_RATE 16625000 28#define CLOCK_TICK_RATE 16625000
29#elif defined CONFIG_ARCH_MX25
30#define CLOCK_TICK_RATE 16000000
31#elif defined CONFIG_ARCH_MXC91231
32#define CLOCK_TICK_RATE 13000000
29#endif 33#endif
30 34
31#endif /* __ASM_ARCH_MXC_TIMEX_H__ */ 35#endif /* __ASM_ARCH_MXC_TIMEX_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index de6fe0365982..082a3908256b 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -26,8 +26,11 @@
26#define __MXC_BOOT_UNCOMPRESS 26#define __MXC_BOOT_UNCOMPRESS
27 27
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <asm/mach-types.h>
29 30
30#define UART(x) (*(volatile unsigned long *)(serial_port + (x))) 31static unsigned long uart_base;
32
33#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
31 34
32#define USR2 0x98 35#define USR2 0x98
33#define USR2_TXFE (1<<14) 36#define USR2_TXFE (1<<14)
@@ -46,19 +49,10 @@
46 49
47static void putc(int ch) 50static void putc(int ch)
48{ 51{
49 static unsigned long serial_port = 0; 52 if (!uart_base)
50 53 return;
51 if (unlikely(serial_port == 0)) { 54 if (!(UART(UCR1) & UCR1_UARTEN))
52 do { 55 return;
53 serial_port = UART1_BASE_ADDR;
54 if (UART(UCR1) & UCR1_UARTEN)
55 break;
56 serial_port = UART2_BASE_ADDR;
57 if (UART(UCR1) & UCR1_UARTEN)
58 break;
59 return;
60 } while (0);
61 }
62 56
63 while (!(UART(USR2) & USR2_TXFE)) 57 while (!(UART(USR2) & USR2_TXFE))
64 barrier(); 58 barrier();
@@ -68,11 +62,49 @@ static void putc(int ch)
68 62
69#define flush() do { } while (0) 63#define flush() do { } while (0)
70 64
71/* 65#define MX1_UART1_BASE_ADDR 0x00206000
72 * nothing to do 66#define MX25_UART1_BASE_ADDR 0x43f90000
73 */ 67#define MX2X_UART1_BASE_ADDR 0x1000a000
74#define arch_decomp_setup() 68#define MX3X_UART1_BASE_ADDR 0x43F90000
69#define MX3X_UART2_BASE_ADDR 0x43F94000
70
71static __inline__ void __arch_decomp_setup(unsigned long arch_id)
72{
73 switch (arch_id) {
74 case MACH_TYPE_MX1ADS:
75 case MACH_TYPE_SCB9328:
76 uart_base = MX1_UART1_BASE_ADDR;
77 break;
78 case MACH_TYPE_MX25_3DS:
79 uart_base = MX25_UART1_BASE_ADDR;
80 break;
81 case MACH_TYPE_IMX27LITE:
82 case MACH_TYPE_MX27_3DS:
83 case MACH_TYPE_MX27ADS:
84 case MACH_TYPE_PCM038:
85 case MACH_TYPE_MX21ADS:
86 uart_base = MX2X_UART1_BASE_ADDR;
87 break;
88 case MACH_TYPE_MX31LITE:
89 case MACH_TYPE_ARMADILLO5X0:
90 case MACH_TYPE_MX31MOBOARD:
91 case MACH_TYPE_QONG:
92 case MACH_TYPE_MX31_3DS:
93 case MACH_TYPE_PCM037:
94 case MACH_TYPE_MX31ADS:
95 case MACH_TYPE_MX35_3DS:
96 case MACH_TYPE_PCM043:
97 uart_base = MX3X_UART1_BASE_ADDR;
98 break;
99 case MACH_TYPE_MAGX_ZN5:
100 uart_base = MX3X_UART2_BASE_ADDR;
101 break;
102 default:
103 break;
104 }
105}
75 106
107#define arch_decomp_setup() __arch_decomp_setup(arch_id)
76#define arch_decomp_wdog() 108#define arch_decomp_wdog()
77 109
78#endif /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */ 110#endif /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */
diff --git a/arch/arm/plat-mxc/iomux-v3.c b/arch/arm/plat-mxc/iomux-v3.c
index 77a078f9513f..851ca99bf1b1 100644
--- a/arch/arm/plat-mxc/iomux-v3.c
+++ b/arch/arm/plat-mxc/iomux-v3.c
@@ -29,7 +29,7 @@
29#include <asm/mach/map.h> 29#include <asm/mach/map.h>
30#include <mach/iomux-v3.h> 30#include <mach/iomux-v3.h>
31 31
32#define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) 32static void __iomem *base;
33 33
34static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG]; 34static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG];
35 35
@@ -45,14 +45,14 @@ int mxc_iomux_v3_setup_pad(struct pad_desc *pad)
45 if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map)) 45 if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map))
46 return -EBUSY; 46 return -EBUSY;
47 if (pad->mux_ctrl_ofs) 47 if (pad->mux_ctrl_ofs)
48 __raw_writel(pad->mux_mode, IOMUX_BASE + pad->mux_ctrl_ofs); 48 __raw_writel(pad->mux_mode, base + pad->mux_ctrl_ofs);
49 49
50 if (pad->select_input_ofs) 50 if (pad->select_input_ofs)
51 __raw_writel(pad->select_input, 51 __raw_writel(pad->select_input,
52 IOMUX_BASE + pad->select_input_ofs); 52 base + pad->select_input_ofs);
53 53
54 if (!(pad->pad_ctrl & NO_PAD_CTRL)) 54 if (!(pad->pad_ctrl & NO_PAD_CTRL) && pad->pad_ctrl_ofs)
55 __raw_writel(pad->pad_ctrl, IOMUX_BASE + pad->pad_ctrl_ofs); 55 __raw_writel(pad->pad_ctrl, base + pad->pad_ctrl_ofs);
56 return 0; 56 return 0;
57} 57}
58EXPORT_SYMBOL(mxc_iomux_v3_setup_pad); 58EXPORT_SYMBOL(mxc_iomux_v3_setup_pad);
@@ -96,3 +96,8 @@ void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count)
96 } 96 }
97} 97}
98EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads); 98EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads);
99
100void mxc_iomux_v3_init(void __iomem *iomux_v3_base)
101{
102 base = iomux_v3_base;
103}
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 8aee76304f8f..778ddfe57d89 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -44,7 +44,7 @@
44#define AVIC_FIPNDH 0x60 /* fast int pending high */ 44#define AVIC_FIPNDH 0x60 /* fast int pending high */
45#define AVIC_FIPNDL 0x64 /* fast int pending low */ 45#define AVIC_FIPNDL 0x64 /* fast int pending low */
46 46
47static void __iomem *avic_base; 47void __iomem *avic_base;
48 48
49int imx_irq_set_priority(unsigned char irq, unsigned char prio) 49int imx_irq_set_priority(unsigned char irq, unsigned char prio)
50{ 50{
@@ -113,11 +113,11 @@ static struct irq_chip mxc_avic_chip = {
113 * interrupts. It registers the interrupt enable and disable functions 113 * interrupts. It registers the interrupt enable and disable functions
114 * to the kernel for each interrupt source. 114 * to the kernel for each interrupt source.
115 */ 115 */
116void __init mxc_init_irq(void) 116void __init mxc_init_irq(void __iomem *irqbase)
117{ 117{
118 int i; 118 int i;
119 119
120 avic_base = IO_ADDRESS(AVIC_BASE_ADDR); 120 avic_base = irqbase;
121 121
122 /* put the AVIC into the reset value with 122 /* put the AVIC into the reset value with
123 * all interrupts disabled 123 * all interrupts disabled
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index ae34198a79dd..5cdbd605ac05 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -32,6 +32,7 @@
32#define MX3_PWMPR 0x10 /* PWM Period Register */ 32#define MX3_PWMPR 0x10 /* PWM Period Register */
33#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) 33#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)
34#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) 34#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
35#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
35#define MX3_PWMCR_EN (1 << 0) 36#define MX3_PWMCR_EN (1 << 0)
36 37
37 38
@@ -55,9 +56,11 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
55 if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) 56 if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
56 return -EINVAL; 57 return -EINVAL;
57 58
58 if (cpu_is_mx27() || cpu_is_mx3()) { 59 if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) {
59 unsigned long long c; 60 unsigned long long c;
60 unsigned long period_cycles, duty_cycles, prescale; 61 unsigned long period_cycles, duty_cycles, prescale;
62 u32 cr;
63
61 c = clk_get_rate(pwm->clk); 64 c = clk_get_rate(pwm->clk);
62 c = c * period_ns; 65 c = c * period_ns;
63 do_div(c, 1000000000); 66 do_div(c, 1000000000);
@@ -72,9 +75,15 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
72 75
73 writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); 76 writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
74 writel(period_cycles, pwm->mmio_base + MX3_PWMPR); 77 writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
75 writel(MX3_PWMCR_PRESCALER(prescale - 1) | 78
76 MX3_PWMCR_CLKSRC_IPG_HIGH | MX3_PWMCR_EN, 79 cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_EN;
77 pwm->mmio_base + MX3_PWMCR); 80
81 if (cpu_is_mx25())
82 cr |= MX3_PWMCR_CLKSRC_IPG;
83 else
84 cr |= MX3_PWMCR_CLKSRC_IPG_HIGH;
85
86 writel(cr, pwm->mmio_base + MX3_PWMCR);
78 } else if (cpu_is_mx1() || cpu_is_mx21()) { 87 } else if (cpu_is_mx1() || cpu_is_mx21()) {
79 /* The PWM subsystem allows for exact frequencies. However, 88 /* The PWM subsystem allows for exact frequencies. However,
80 * I cannot connect a scope on my device to the PWM line and 89 * I cannot connect a scope on my device to the PWM line and
@@ -118,6 +127,8 @@ EXPORT_SYMBOL(pwm_enable);
118 127
119void pwm_disable(struct pwm_device *pwm) 128void pwm_disable(struct pwm_device *pwm)
120{ 129{
130 writel(0, pwm->mmio_base + MX3_PWMCR);
131
121 if (pwm->clk_enabled) { 132 if (pwm->clk_enabled) {
122 clk_disable(pwm->clk); 133 clk_disable(pwm->clk);
123 pwm->clk_enabled = 0; 134 pwm->clk_enabled = 0;
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 79c37577c916..97f42799fa58 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -27,32 +27,38 @@
27#include <linux/delay.h> 27#include <linux/delay.h>
28 28
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/common.h>
30#include <asm/proc-fns.h> 31#include <asm/proc-fns.h>
31#include <asm/system.h> 32#include <asm/system.h>
32 33
33#ifdef CONFIG_ARCH_MX1 34static void __iomem *wdog_base;
34#define WDOG_WCR_REG IO_ADDRESS(WDT_BASE_ADDR)
35#define WDOG_WCR_ENABLE (1 << 0)
36#else
37#define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR)
38#define WDOG_WCR_ENABLE (1 << 2)
39#endif
40 35
41/* 36/*
42 * Reset the system. It is called by machine_restart(). 37 * Reset the system. It is called by machine_restart().
43 */ 38 */
44void arch_reset(char mode, const char *cmd) 39void arch_reset(char mode, const char *cmd)
45{ 40{
46 if (!cpu_is_mx1()) { 41 unsigned int wcr_enable;
42
43#ifdef CONFIG_ARCH_MXC91231
44 if (cpu_is_mxc91231()) {
45 mxc91231_arch_reset(mode, cmd);
46 return;
47 }
48#endif
49 if (cpu_is_mx1()) {
50 wcr_enable = (1 << 0);
51 } else {
47 struct clk *clk; 52 struct clk *clk;
48 53
49 clk = clk_get_sys("imx-wdt.0", NULL); 54 clk = clk_get_sys("imx-wdt.0", NULL);
50 if (!IS_ERR(clk)) 55 if (!IS_ERR(clk))
51 clk_enable(clk); 56 clk_enable(clk);
57 wcr_enable = (1 << 2);
52 } 58 }
53 59
54 /* Assert SRS signal */ 60 /* Assert SRS signal */
55 __raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG); 61 __raw_writew(wcr_enable, wdog_base);
56 62
57 /* wait for reset to assert... */ 63 /* wait for reset to assert... */
58 mdelay(500); 64 mdelay(500);
@@ -65,3 +71,8 @@ void arch_reset(char mode, const char *cmd)
65 /* we'll take a jump through zero as a poor second */ 71 /* we'll take a jump through zero as a poor second */
66 cpu_reset(0); 72 cpu_reset(0);
67} 73}
74
75void mxc_arch_reset_init(void __iomem *base)
76{
77 wdog_base = base;
78}
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 88fb3a57e029..844567ee35fe 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -47,7 +47,7 @@
47#define MX2_TSTAT_CAPT (1 << 1) 47#define MX2_TSTAT_CAPT (1 << 1)
48#define MX2_TSTAT_COMP (1 << 0) 48#define MX2_TSTAT_COMP (1 << 0)
49 49
50/* MX31, MX35 */ 50/* MX31, MX35, MX25, MXC91231 */
51#define MX3_TCTL_WAITEN (1 << 3) 51#define MX3_TCTL_WAITEN (1 << 3)
52#define MX3_TCTL_CLK_IPG (1 << 6) 52#define MX3_TCTL_CLK_IPG (1 << 6)
53#define MX3_TCTL_FRR (1 << 9) 53#define MX3_TCTL_FRR (1 << 9)
@@ -66,7 +66,7 @@ static inline void gpt_irq_disable(void)
66{ 66{
67 unsigned int tmp; 67 unsigned int tmp;
68 68
69 if (cpu_is_mx3()) 69 if (cpu_is_mx3() || cpu_is_mx25())
70 __raw_writel(0, timer_base + MX3_IR); 70 __raw_writel(0, timer_base + MX3_IR);
71 else { 71 else {
72 tmp = __raw_readl(timer_base + MXC_TCTL); 72 tmp = __raw_readl(timer_base + MXC_TCTL);
@@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void)
76 76
77static inline void gpt_irq_enable(void) 77static inline void gpt_irq_enable(void)
78{ 78{
79 if (cpu_is_mx3()) 79 if (cpu_is_mx3() || cpu_is_mx25())
80 __raw_writel(1<<0, timer_base + MX3_IR); 80 __raw_writel(1<<0, timer_base + MX3_IR);
81 else { 81 else {
82 __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, 82 __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
@@ -90,7 +90,7 @@ static void gpt_irq_acknowledge(void)
90 __raw_writel(0, timer_base + MX1_2_TSTAT); 90 __raw_writel(0, timer_base + MX1_2_TSTAT);
91 if (cpu_is_mx2()) 91 if (cpu_is_mx2())
92 __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT); 92 __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT);
93 if (cpu_is_mx3()) 93 if (cpu_is_mx3() || cpu_is_mx25())
94 __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT); 94 __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT);
95} 95}
96 96
@@ -117,7 +117,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
117{ 117{
118 unsigned int c = clk_get_rate(timer_clk); 118 unsigned int c = clk_get_rate(timer_clk);
119 119
120 if (cpu_is_mx3()) 120 if (cpu_is_mx3() || cpu_is_mx25())
121 clocksource_mxc.read = mx3_get_cycles; 121 clocksource_mxc.read = mx3_get_cycles;
122 122
123 clocksource_mxc.mult = clocksource_hz2mult(c, 123 clocksource_mxc.mult = clocksource_hz2mult(c,
@@ -180,7 +180,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
180 180
181 if (mode != clockevent_mode) { 181 if (mode != clockevent_mode) {
182 /* Set event time into far-far future */ 182 /* Set event time into far-far future */
183 if (cpu_is_mx3()) 183 if (cpu_is_mx3() || cpu_is_mx25())
184 __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3, 184 __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3,
185 timer_base + MX3_TCMP); 185 timer_base + MX3_TCMP);
186 else 186 else
@@ -233,7 +233,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
233 struct clock_event_device *evt = &clockevent_mxc; 233 struct clock_event_device *evt = &clockevent_mxc;
234 uint32_t tstat; 234 uint32_t tstat;
235 235
236 if (cpu_is_mx3()) 236 if (cpu_is_mx3() || cpu_is_mx25())
237 tstat = __raw_readl(timer_base + MX3_TSTAT); 237 tstat = __raw_readl(timer_base + MX3_TSTAT);
238 else 238 else
239 tstat = __raw_readl(timer_base + MX1_2_TSTAT); 239 tstat = __raw_readl(timer_base + MX1_2_TSTAT);
@@ -264,7 +264,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
264{ 264{
265 unsigned int c = clk_get_rate(timer_clk); 265 unsigned int c = clk_get_rate(timer_clk);
266 266
267 if (cpu_is_mx3()) 267 if (cpu_is_mx3() || cpu_is_mx25())
268 clockevent_mxc.set_next_event = mx3_set_next_event; 268 clockevent_mxc.set_next_event = mx3_set_next_event;
269 269
270 clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC, 270 clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -281,30 +281,13 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
281 return 0; 281 return 0;
282} 282}
283 283
284void __init mxc_timer_init(struct clk *timer_clk) 284void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
285{ 285{
286 uint32_t tctl_val; 286 uint32_t tctl_val;
287 int irq;
288 287
289 clk_enable(timer_clk); 288 clk_enable(timer_clk);
290 289
291 if (cpu_is_mx1()) { 290 timer_base = base;
292#ifdef CONFIG_ARCH_MX1
293 timer_base = IO_ADDRESS(TIM1_BASE_ADDR);
294 irq = TIM1_INT;
295#endif
296 } else if (cpu_is_mx2()) {
297#ifdef CONFIG_ARCH_MX2
298 timer_base = IO_ADDRESS(GPT1_BASE_ADDR);
299 irq = MXC_INT_GPT1;
300#endif
301 } else if (cpu_is_mx3()) {
302#ifdef CONFIG_ARCH_MX3
303 timer_base = IO_ADDRESS(GPT1_BASE_ADDR);
304 irq = MXC_INT_GPT;
305#endif
306 } else
307 BUG();
308 291
309 /* 292 /*
310 * Initialise to a known state (all timers off, and timing reset) 293 * Initialise to a known state (all timers off, and timing reset)
@@ -313,7 +296,7 @@ void __init mxc_timer_init(struct clk *timer_clk)
313 __raw_writel(0, timer_base + MXC_TCTL); 296 __raw_writel(0, timer_base + MXC_TCTL);
314 __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ 297 __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
315 298
316 if (cpu_is_mx3()) 299 if (cpu_is_mx3() || cpu_is_mx25())
317 tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN; 300 tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN;
318 else 301 else
319 tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; 302 tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
index be4eefda4767..9395898dd49a 100644
--- a/arch/arm/plat-omap/debug-leds.c
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -281,24 +281,27 @@ static int /* __init */ fpga_probe(struct platform_device *pdev)
281 return 0; 281 return 0;
282} 282}
283 283
284static int fpga_suspend_late(struct platform_device *pdev, pm_message_t mesg) 284static int fpga_suspend_noirq(struct device *dev)
285{ 285{
286 __raw_writew(~0, &fpga->leds); 286 __raw_writew(~0, &fpga->leds);
287 return 0; 287 return 0;
288} 288}
289 289
290static int fpga_resume_early(struct platform_device *pdev) 290static int fpga_resume_noirq(struct device *dev)
291{ 291{
292 __raw_writew(~hw_led_state, &fpga->leds); 292 __raw_writew(~hw_led_state, &fpga->leds);
293 return 0; 293 return 0;
294} 294}
295 295
296static struct dev_pm_ops fpga_dev_pm_ops = {
297 .suspend_noirq = fpga_suspend_noirq,
298 .resume_noirq = fpga_resume_noirq,
299};
296 300
297static struct platform_driver led_driver = { 301static struct platform_driver led_driver = {
298 .driver.name = "omap_dbg_led", 302 .driver.name = "omap_dbg_led",
303 .driver.pm = &fpga_dev_pm_ops,
299 .probe = fpga_probe, 304 .probe = fpga_probe,
300 .suspend_late = fpga_suspend_late,
301 .resume_early = fpga_resume_early,
302}; 305};
303 306
304static int __init fpga_init(void) 307static int __init fpga_init(void)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index e3ac94f09006..9b00f4cbc903 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1127,6 +1127,11 @@ int omap_dma_running(void)
1127void omap_dma_link_lch(int lch_head, int lch_queue) 1127void omap_dma_link_lch(int lch_head, int lch_queue)
1128{ 1128{
1129 if (omap_dma_in_1510_mode()) { 1129 if (omap_dma_in_1510_mode()) {
1130 if (lch_head == lch_queue) {
1131 dma_write(dma_read(CCR(lch_head)) | (3 << 8),
1132 CCR(lch_head));
1133 return;
1134 }
1130 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); 1135 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
1131 BUG(); 1136 BUG();
1132 return; 1137 return;
@@ -1149,6 +1154,11 @@ EXPORT_SYMBOL(omap_dma_link_lch);
1149void omap_dma_unlink_lch(int lch_head, int lch_queue) 1154void omap_dma_unlink_lch(int lch_head, int lch_queue)
1150{ 1155{
1151 if (omap_dma_in_1510_mode()) { 1156 if (omap_dma_in_1510_mode()) {
1157 if (lch_head == lch_queue) {
1158 dma_write(dma_read(CCR(lch_head)) & ~(3 << 8),
1159 CCR(lch_head));
1160 return;
1161 }
1152 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); 1162 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
1153 BUG(); 1163 BUG();
1154 return; 1164 return;
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9298bc0ab171..176c86e5531d 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -138,6 +138,32 @@
138#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 138#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
139#define OMAP24XX_GPIO_SETDATAOUT 0x0094 139#define OMAP24XX_GPIO_SETDATAOUT 0x0094
140 140
141#define OMAP4_GPIO_REVISION 0x0000
142#define OMAP4_GPIO_SYSCONFIG 0x0010
143#define OMAP4_GPIO_EOI 0x0020
144#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024
145#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028
146#define OMAP4_GPIO_IRQSTATUS0 0x002c
147#define OMAP4_GPIO_IRQSTATUS1 0x0030
148#define OMAP4_GPIO_IRQSTATUSSET0 0x0034
149#define OMAP4_GPIO_IRQSTATUSSET1 0x0038
150#define OMAP4_GPIO_IRQSTATUSCLR0 0x003c
151#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040
152#define OMAP4_GPIO_IRQWAKEN0 0x0044
153#define OMAP4_GPIO_IRQWAKEN1 0x0048
154#define OMAP4_GPIO_SYSSTATUS 0x0104
155#define OMAP4_GPIO_CTRL 0x0130
156#define OMAP4_GPIO_OE 0x0134
157#define OMAP4_GPIO_DATAIN 0x0138
158#define OMAP4_GPIO_DATAOUT 0x013c
159#define OMAP4_GPIO_LEVELDETECT0 0x0140
160#define OMAP4_GPIO_LEVELDETECT1 0x0144
161#define OMAP4_GPIO_RISINGDETECT 0x0148
162#define OMAP4_GPIO_FALLINGDETECT 0x014c
163#define OMAP4_GPIO_DEBOUNCENABLE 0x0150
164#define OMAP4_GPIO_DEBOUNCINGTIME 0x0154
165#define OMAP4_GPIO_CLEARDATAOUT 0x0190
166#define OMAP4_GPIO_SETDATAOUT 0x0194
141/* 167/*
142 * omap34xx specific GPIO registers 168 * omap34xx specific GPIO registers
143 */ 169 */
@@ -386,12 +412,16 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
386 reg += OMAP850_GPIO_DIR_CONTROL; 412 reg += OMAP850_GPIO_DIR_CONTROL;
387 break; 413 break;
388#endif 414#endif
389#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 415#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
390 defined(CONFIG_ARCH_OMAP4)
391 case METHOD_GPIO_24XX: 416 case METHOD_GPIO_24XX:
392 reg += OMAP24XX_GPIO_OE; 417 reg += OMAP24XX_GPIO_OE;
393 break; 418 break;
394#endif 419#endif
420#if defined(CONFIG_ARCH_OMAP4)
421 case METHOD_GPIO_24XX:
422 reg += OMAP4_GPIO_OE;
423 break;
424#endif
395 default: 425 default:
396 WARN_ON(1); 426 WARN_ON(1);
397 return; 427 return;
@@ -459,8 +489,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
459 l &= ~(1 << gpio); 489 l &= ~(1 << gpio);
460 break; 490 break;
461#endif 491#endif
462#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 492#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
463 defined(CONFIG_ARCH_OMAP4)
464 case METHOD_GPIO_24XX: 493 case METHOD_GPIO_24XX:
465 if (enable) 494 if (enable)
466 reg += OMAP24XX_GPIO_SETDATAOUT; 495 reg += OMAP24XX_GPIO_SETDATAOUT;
@@ -469,6 +498,15 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
469 l = 1 << gpio; 498 l = 1 << gpio;
470 break; 499 break;
471#endif 500#endif
501#ifdef CONFIG_ARCH_OMAP4
502 case METHOD_GPIO_24XX:
503 if (enable)
504 reg += OMAP4_GPIO_SETDATAOUT;
505 else
506 reg += OMAP4_GPIO_CLEARDATAOUT;
507 l = 1 << gpio;
508 break;
509#endif
472 default: 510 default:
473 WARN_ON(1); 511 WARN_ON(1);
474 return; 512 return;
@@ -509,12 +547,16 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
509 reg += OMAP850_GPIO_DATA_INPUT; 547 reg += OMAP850_GPIO_DATA_INPUT;
510 break; 548 break;
511#endif 549#endif
512#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 550#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
513 defined(CONFIG_ARCH_OMAP4)
514 case METHOD_GPIO_24XX: 551 case METHOD_GPIO_24XX:
515 reg += OMAP24XX_GPIO_DATAIN; 552 reg += OMAP24XX_GPIO_DATAIN;
516 break; 553 break;
517#endif 554#endif
555#ifdef CONFIG_ARCH_OMAP4
556 case METHOD_GPIO_24XX:
557 reg += OMAP4_GPIO_DATAIN;
558 break;
559#endif
518 default: 560 default:
519 return -EINVAL; 561 return -EINVAL;
520 } 562 }
@@ -589,7 +631,11 @@ void omap_set_gpio_debounce(int gpio, int enable)
589 631
590 bank = get_gpio_bank(gpio); 632 bank = get_gpio_bank(gpio);
591 reg = bank->base; 633 reg = bank->base;
634#ifdef CONFIG_ARCH_OMAP4
635 reg += OMAP4_GPIO_DEBOUNCENABLE;
636#else
592 reg += OMAP24XX_GPIO_DEBOUNCE_EN; 637 reg += OMAP24XX_GPIO_DEBOUNCE_EN;
638#endif
593 639
594 spin_lock_irqsave(&bank->lock, flags); 640 spin_lock_irqsave(&bank->lock, flags);
595 val = __raw_readl(reg); 641 val = __raw_readl(reg);
@@ -626,7 +672,11 @@ void omap_set_gpio_debounce_time(int gpio, int enc_time)
626 reg = bank->base; 672 reg = bank->base;
627 673
628 enc_time &= 0xff; 674 enc_time &= 0xff;
675#ifdef CONFIG_ARCH_OMAP4
676 reg += OMAP4_GPIO_DEBOUNCINGTIME;
677#else
629 reg += OMAP24XX_GPIO_DEBOUNCE_VAL; 678 reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
679#endif
630 __raw_writel(enc_time, reg); 680 __raw_writel(enc_time, reg);
631} 681}
632EXPORT_SYMBOL(omap_set_gpio_debounce_time); 682EXPORT_SYMBOL(omap_set_gpio_debounce_time);
@@ -638,23 +688,46 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
638{ 688{
639 void __iomem *base = bank->base; 689 void __iomem *base = bank->base;
640 u32 gpio_bit = 1 << gpio; 690 u32 gpio_bit = 1 << gpio;
691 u32 val;
641 692
642 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, 693 if (cpu_is_omap44xx()) {
643 trigger & IRQ_TYPE_LEVEL_LOW); 694 MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
644 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, 695 trigger & IRQ_TYPE_LEVEL_LOW);
645 trigger & IRQ_TYPE_LEVEL_HIGH); 696 MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
646 MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, 697 trigger & IRQ_TYPE_LEVEL_HIGH);
647 trigger & IRQ_TYPE_EDGE_RISING); 698 MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
648 MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, 699 trigger & IRQ_TYPE_EDGE_RISING);
649 trigger & IRQ_TYPE_EDGE_FALLING); 700 MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
650 701 trigger & IRQ_TYPE_EDGE_FALLING);
702 } else {
703 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
704 trigger & IRQ_TYPE_LEVEL_LOW);
705 MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
706 trigger & IRQ_TYPE_LEVEL_HIGH);
707 MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
708 trigger & IRQ_TYPE_EDGE_RISING);
709 MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
710 trigger & IRQ_TYPE_EDGE_FALLING);
711 }
651 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { 712 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
652 if (trigger != 0) 713 if (cpu_is_omap44xx()) {
653 __raw_writel(1 << gpio, bank->base 714 if (trigger != 0)
715 __raw_writel(1 << gpio, bank->base+
716 OMAP4_GPIO_IRQWAKEN0);
717 else {
718 val = __raw_readl(bank->base +
719 OMAP4_GPIO_IRQWAKEN0);
720 __raw_writel(val & (~(1 << gpio)), bank->base +
721 OMAP4_GPIO_IRQWAKEN0);
722 }
723 } else {
724 if (trigger != 0)
725 __raw_writel(1 << gpio, bank->base
654 + OMAP24XX_GPIO_SETWKUENA); 726 + OMAP24XX_GPIO_SETWKUENA);
655 else 727 else
656 __raw_writel(1 << gpio, bank->base 728 __raw_writel(1 << gpio, bank->base
657 + OMAP24XX_GPIO_CLEARWKUENA); 729 + OMAP24XX_GPIO_CLEARWKUENA);
730 }
658 } else { 731 } else {
659 if (trigger != 0) 732 if (trigger != 0)
660 bank->enabled_non_wakeup_gpios |= gpio_bit; 733 bank->enabled_non_wakeup_gpios |= gpio_bit;
@@ -662,9 +735,15 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
662 bank->enabled_non_wakeup_gpios &= ~gpio_bit; 735 bank->enabled_non_wakeup_gpios &= ~gpio_bit;
663 } 736 }
664 737
665 bank->level_mask = 738 if (cpu_is_omap44xx()) {
666 __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | 739 bank->level_mask =
667 __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); 740 __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
741 __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
742 } else {
743 bank->level_mask =
744 __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
745 __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
746 }
668} 747}
669#endif 748#endif
670 749
@@ -828,12 +907,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
828 reg += OMAP850_GPIO_INT_STATUS; 907 reg += OMAP850_GPIO_INT_STATUS;
829 break; 908 break;
830#endif 909#endif
831#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 910#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
832 defined(CONFIG_ARCH_OMAP4)
833 case METHOD_GPIO_24XX: 911 case METHOD_GPIO_24XX:
834 reg += OMAP24XX_GPIO_IRQSTATUS1; 912 reg += OMAP24XX_GPIO_IRQSTATUS1;
835 break; 913 break;
836#endif 914#endif
915#if defined(CONFIG_ARCH_OMAP4)
916 case METHOD_GPIO_24XX:
917 reg += OMAP4_GPIO_IRQSTATUS0;
918 break;
919#endif
837 default: 920 default:
838 WARN_ON(1); 921 WARN_ON(1);
839 return; 922 return;
@@ -843,12 +926,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
843 /* Workaround for clearing DSP GPIO interrupts to allow retention */ 926 /* Workaround for clearing DSP GPIO interrupts to allow retention */
844#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 927#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
845 reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2; 928 reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
846 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 929#endif
930#if defined(CONFIG_ARCH_OMAP4)
931 reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
932#endif
933 if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
847 __raw_writel(gpio_mask, reg); 934 __raw_writel(gpio_mask, reg);
848 935
849 /* Flush posted write for the irq status to avoid spurious interrupts */ 936 /* Flush posted write for the irq status to avoid spurious interrupts */
850 __raw_readl(reg); 937 __raw_readl(reg);
851#endif 938 }
852} 939}
853 940
854static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) 941static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
@@ -898,13 +985,18 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
898 inv = 1; 985 inv = 1;
899 break; 986 break;
900#endif 987#endif
901#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 988#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
902 defined(CONFIG_ARCH_OMAP4)
903 case METHOD_GPIO_24XX: 989 case METHOD_GPIO_24XX:
904 reg += OMAP24XX_GPIO_IRQENABLE1; 990 reg += OMAP24XX_GPIO_IRQENABLE1;
905 mask = 0xffffffff; 991 mask = 0xffffffff;
906 break; 992 break;
907#endif 993#endif
994#if defined(CONFIG_ARCH_OMAP4)
995 case METHOD_GPIO_24XX:
996 reg += OMAP4_GPIO_IRQSTATUSSET0;
997 mask = 0xffffffff;
998 break;
999#endif
908 default: 1000 default:
909 WARN_ON(1); 1001 WARN_ON(1);
910 return 0; 1002 return 0;
@@ -972,8 +1064,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
972 l |= gpio_mask; 1064 l |= gpio_mask;
973 break; 1065 break;
974#endif 1066#endif
975#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 1067#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
976 defined(CONFIG_ARCH_OMAP4)
977 case METHOD_GPIO_24XX: 1068 case METHOD_GPIO_24XX:
978 if (enable) 1069 if (enable)
979 reg += OMAP24XX_GPIO_SETIRQENABLE1; 1070 reg += OMAP24XX_GPIO_SETIRQENABLE1;
@@ -982,6 +1073,15 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
982 l = gpio_mask; 1073 l = gpio_mask;
983 break; 1074 break;
984#endif 1075#endif
1076#ifdef CONFIG_ARCH_OMAP4
1077 case METHOD_GPIO_24XX:
1078 if (enable)
1079 reg += OMAP4_GPIO_IRQSTATUSSET0;
1080 else
1081 reg += OMAP4_GPIO_IRQSTATUSCLR0;
1082 l = gpio_mask;
1083 break;
1084#endif
985 default: 1085 default:
986 WARN_ON(1); 1086 WARN_ON(1);
987 return; 1087 return;
@@ -1157,11 +1257,14 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
1157 if (bank->method == METHOD_GPIO_850) 1257 if (bank->method == METHOD_GPIO_850)
1158 isr_reg = bank->base + OMAP850_GPIO_INT_STATUS; 1258 isr_reg = bank->base + OMAP850_GPIO_INT_STATUS;
1159#endif 1259#endif
1160#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 1260#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1161 defined(CONFIG_ARCH_OMAP4)
1162 if (bank->method == METHOD_GPIO_24XX) 1261 if (bank->method == METHOD_GPIO_24XX)
1163 isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; 1262 isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
1164#endif 1263#endif
1264#if defined(CONFIG_ARCH_OMAP4)
1265 if (bank->method == METHOD_GPIO_24XX)
1266 isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
1267#endif
1165 while(1) { 1268 while(1) {
1166 u32 isr_saved, level_mask = 0; 1269 u32 isr_saved, level_mask = 0;
1167 u32 enabled; 1270 u32 enabled;
@@ -1315,8 +1418,9 @@ static struct irq_chip mpuio_irq_chip = {
1315 1418
1316#include <linux/platform_device.h> 1419#include <linux/platform_device.h>
1317 1420
1318static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg) 1421static int omap_mpuio_suspend_noirq(struct device *dev)
1319{ 1422{
1423 struct platform_device *pdev = to_platform_device(dev);
1320 struct gpio_bank *bank = platform_get_drvdata(pdev); 1424 struct gpio_bank *bank = platform_get_drvdata(pdev);
1321 void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; 1425 void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
1322 unsigned long flags; 1426 unsigned long flags;
@@ -1329,8 +1433,9 @@ static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t me
1329 return 0; 1433 return 0;
1330} 1434}
1331 1435
1332static int omap_mpuio_resume_early(struct platform_device *pdev) 1436static int omap_mpuio_resume_noirq(struct device *dev)
1333{ 1437{
1438 struct platform_device *pdev = to_platform_device(dev);
1334 struct gpio_bank *bank = platform_get_drvdata(pdev); 1439 struct gpio_bank *bank = platform_get_drvdata(pdev);
1335 void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; 1440 void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
1336 unsigned long flags; 1441 unsigned long flags;
@@ -1342,14 +1447,18 @@ static int omap_mpuio_resume_early(struct platform_device *pdev)
1342 return 0; 1447 return 0;
1343} 1448}
1344 1449
1450static struct dev_pm_ops omap_mpuio_dev_pm_ops = {
1451 .suspend_noirq = omap_mpuio_suspend_noirq,
1452 .resume_noirq = omap_mpuio_resume_noirq,
1453};
1454
1345/* use platform_driver for this, now that there's no longer any 1455/* use platform_driver for this, now that there's no longer any
1346 * point to sys_device (other than not disturbing old code). 1456 * point to sys_device (other than not disturbing old code).
1347 */ 1457 */
1348static struct platform_driver omap_mpuio_driver = { 1458static struct platform_driver omap_mpuio_driver = {
1349 .suspend_late = omap_mpuio_suspend_late,
1350 .resume_early = omap_mpuio_resume_early,
1351 .driver = { 1459 .driver = {
1352 .name = "mpuio", 1460 .name = "mpuio",
1461 .pm = &omap_mpuio_dev_pm_ops,
1353 }, 1462 },
1354}; 1463};
1355 1464
@@ -1638,7 +1747,7 @@ static int __init _omap_gpio_init(void)
1638 1747
1639 gpio_bank_count = OMAP34XX_NR_GPIOS; 1748 gpio_bank_count = OMAP34XX_NR_GPIOS;
1640 gpio_bank = gpio_bank_44xx; 1749 gpio_bank = gpio_bank_44xx;
1641 rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); 1750 rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION);
1642 printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n", 1751 printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n",
1643 (rev >> 4) & 0x0f, rev & 0x0f); 1752 (rev >> 4) & 0x0f, rev & 0x0f);
1644 } 1753 }
@@ -1672,7 +1781,16 @@ static int __init _omap_gpio_init(void)
1672 static const u32 non_wakeup_gpios[] = { 1781 static const u32 non_wakeup_gpios[] = {
1673 0xe203ffc0, 0x08700040 1782 0xe203ffc0, 0x08700040
1674 }; 1783 };
1675 1784 if (cpu_is_omap44xx()) {
1785 __raw_writel(0xffffffff, bank->base +
1786 OMAP4_GPIO_IRQSTATUSCLR0);
1787 __raw_writew(0x0015, bank->base +
1788 OMAP4_GPIO_SYSCONFIG);
1789 __raw_writel(0x00000000, bank->base +
1790 OMAP4_GPIO_DEBOUNCENABLE);
1791 /* Initialize interface clock ungated, module enabled */
1792 __raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
1793 } else {
1676 __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); 1794 __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
1677 __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); 1795 __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
1678 __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); 1796 __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG);
@@ -1680,12 +1798,12 @@ static int __init _omap_gpio_init(void)
1680 1798
1681 /* Initialize interface clock ungated, module enabled */ 1799 /* Initialize interface clock ungated, module enabled */
1682 __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); 1800 __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
1801 }
1683 if (i < ARRAY_SIZE(non_wakeup_gpios)) 1802 if (i < ARRAY_SIZE(non_wakeup_gpios))
1684 bank->non_wakeup_gpios = non_wakeup_gpios[i]; 1803 bank->non_wakeup_gpios = non_wakeup_gpios[i];
1685 gpio_count = 32; 1804 gpio_count = 32;
1686 } 1805 }
1687#endif 1806#endif
1688
1689 /* REVISIT eventually switch from OMAP-specific gpio structs 1807 /* REVISIT eventually switch from OMAP-specific gpio structs
1690 * over to the generic ones 1808 * over to the generic ones
1691 */ 1809 */
@@ -1771,14 +1889,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
1771 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; 1889 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
1772 break; 1890 break;
1773#endif 1891#endif
1774#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 1892#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1775 defined(CONFIG_ARCH_OMAP4)
1776 case METHOD_GPIO_24XX: 1893 case METHOD_GPIO_24XX:
1777 wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; 1894 wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
1778 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; 1895 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
1779 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; 1896 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
1780 break; 1897 break;
1781#endif 1898#endif
1899#ifdef CONFIG_ARCH_OMAP4
1900 case METHOD_GPIO_24XX:
1901 wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0;
1902 wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
1903 wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
1904 break;
1905#endif
1782 default: 1906 default:
1783 continue; 1907 continue;
1784 } 1908 }
@@ -1813,13 +1937,18 @@ static int omap_gpio_resume(struct sys_device *dev)
1813 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; 1937 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
1814 break; 1938 break;
1815#endif 1939#endif
1816#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 1940#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1817 defined(CONFIG_ARCH_OMAP4)
1818 case METHOD_GPIO_24XX: 1941 case METHOD_GPIO_24XX:
1819 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; 1942 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
1820 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; 1943 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
1821 break; 1944 break;
1822#endif 1945#endif
1946#ifdef CONFIG_ARCH_OMAP4
1947 case METHOD_GPIO_24XX:
1948 wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
1949 wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
1950 break;
1951#endif
1823 default: 1952 default:
1824 continue; 1953 continue;
1825 } 1954 }
@@ -1863,21 +1992,29 @@ void omap2_gpio_prepare_for_retention(void)
1863 1992
1864 if (!(bank->enabled_non_wakeup_gpios)) 1993 if (!(bank->enabled_non_wakeup_gpios))
1865 continue; 1994 continue;
1866#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 1995#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1867 defined(CONFIG_ARCH_OMAP4)
1868 bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); 1996 bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
1869 l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); 1997 l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
1870 l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); 1998 l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
1871#endif 1999#endif
2000#ifdef CONFIG_ARCH_OMAP4
2001 bank->saved_datain = __raw_readl(bank->base +
2002 OMAP4_GPIO_DATAIN);
2003 l1 = __raw_readl(bank->base + OMAP4_GPIO_FALLINGDETECT);
2004 l2 = __raw_readl(bank->base + OMAP4_GPIO_RISINGDETECT);
2005#endif
1872 bank->saved_fallingdetect = l1; 2006 bank->saved_fallingdetect = l1;
1873 bank->saved_risingdetect = l2; 2007 bank->saved_risingdetect = l2;
1874 l1 &= ~bank->enabled_non_wakeup_gpios; 2008 l1 &= ~bank->enabled_non_wakeup_gpios;
1875 l2 &= ~bank->enabled_non_wakeup_gpios; 2009 l2 &= ~bank->enabled_non_wakeup_gpios;
1876#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 2010#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1877 defined(CONFIG_ARCH_OMAP4)
1878 __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); 2011 __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
1879 __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT); 2012 __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
1880#endif 2013#endif
2014#ifdef CONFIG_ARCH_OMAP4
2015 __raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
2016 __raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
2017#endif
1881 c++; 2018 c++;
1882 } 2019 }
1883 if (!c) { 2020 if (!c) {
@@ -1899,27 +2036,29 @@ void omap2_gpio_resume_after_retention(void)
1899 2036
1900 if (!(bank->enabled_non_wakeup_gpios)) 2037 if (!(bank->enabled_non_wakeup_gpios))
1901 continue; 2038 continue;
1902#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 2039#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1903 defined(CONFIG_ARCH_OMAP4)
1904 __raw_writel(bank->saved_fallingdetect, 2040 __raw_writel(bank->saved_fallingdetect,
1905 bank->base + OMAP24XX_GPIO_FALLINGDETECT); 2041 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
1906 __raw_writel(bank->saved_risingdetect, 2042 __raw_writel(bank->saved_risingdetect,
1907 bank->base + OMAP24XX_GPIO_RISINGDETECT); 2043 bank->base + OMAP24XX_GPIO_RISINGDETECT);
2044 l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
2045#endif
2046#ifdef CONFIG_ARCH_OMAP4
2047 __raw_writel(bank->saved_fallingdetect,
2048 bank->base + OMAP4_GPIO_FALLINGDETECT);
2049 __raw_writel(bank->saved_risingdetect,
2050 bank->base + OMAP4_GPIO_RISINGDETECT);
2051 l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
1908#endif 2052#endif
1909 /* Check if any of the non-wakeup interrupt GPIOs have changed 2053 /* Check if any of the non-wakeup interrupt GPIOs have changed
1910 * state. If so, generate an IRQ by software. This is 2054 * state. If so, generate an IRQ by software. This is
1911 * horribly racy, but it's the best we can do to work around 2055 * horribly racy, but it's the best we can do to work around
1912 * this silicon bug. */ 2056 * this silicon bug. */
1913#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
1914 defined(CONFIG_ARCH_OMAP4)
1915 l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
1916#endif
1917 l ^= bank->saved_datain; 2057 l ^= bank->saved_datain;
1918 l &= bank->non_wakeup_gpios; 2058 l &= bank->non_wakeup_gpios;
1919 if (l) { 2059 if (l) {
1920 u32 old0, old1; 2060 u32 old0, old1;
1921#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ 2061#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
1922 defined(CONFIG_ARCH_OMAP4)
1923 old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); 2062 old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
1924 old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); 2063 old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
1925 __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0); 2064 __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
@@ -1927,6 +2066,20 @@ void omap2_gpio_resume_after_retention(void)
1927 __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0); 2066 __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
1928 __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1); 2067 __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
1929#endif 2068#endif
2069#ifdef CONFIG_ARCH_OMAP4
2070 old0 = __raw_readl(bank->base +
2071 OMAP4_GPIO_LEVELDETECT0);
2072 old1 = __raw_readl(bank->base +
2073 OMAP4_GPIO_LEVELDETECT1);
2074 __raw_writel(old0 | l, bank->base +
2075 OMAP4_GPIO_LEVELDETECT0);
2076 __raw_writel(old1 | l, bank->base +
2077 OMAP4_GPIO_LEVELDETECT1);
2078 __raw_writel(old0, bank->base +
2079 OMAP4_GPIO_LEVELDETECT0);
2080 __raw_writel(old1, bank->base +
2081 OMAP4_GPIO_LEVELDETECT1);
2082#endif
1930 } 2083 }
1931 } 2084 }
1932 2085
diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h
index 7b939cc01962..72f680b7180d 100644
--- a/arch/arm/plat-omap/include/mach/dma.h
+++ b/arch/arm/plat-omap/include/mach/dma.h
@@ -122,6 +122,11 @@
122#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0) 122#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0)
123#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4) 123#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4)
124 124
125/* Additional registers available on OMAP4 */
126#define OMAP_DMA4_CDP(n) (0x60 * (n) + 0xd0)
127#define OMAP_DMA4_CNDP(n) (0x60 * (n) + 0xd4)
128#define OMAP_DMA4_CCDN(n) (0x60 * (n) + 0xd8)
129
125/* Dummy defines to keep multi-omap compiles happy */ 130/* Dummy defines to keep multi-omap compiles happy */
126#define OMAP1_DMA_REVISION 0 131#define OMAP1_DMA_REVISION 0
127#define OMAP1_DMA_IRQSTATUS_L0 0 132#define OMAP1_DMA_IRQSTATUS_L0 0
@@ -311,6 +316,89 @@
311#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */ 316#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */
312#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */ 317#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */
313 318
319/* DMA request lines for 44xx */
320#define OMAP44XX_DMA_DSS_DISPC_REQ 6 /* S_DMA_5 */
321#define OMAP44XX_DMA_SYS_REQ2 7 /* S_DMA_6 */
322#define OMAP44XX_DMA_ISS_REQ1 9 /* S_DMA_8 */
323#define OMAP44XX_DMA_ISS_REQ2 10 /* S_DMA_9 */
324#define OMAP44XX_DMA_ISS_REQ3 12 /* S_DMA_11 */
325#define OMAP44XX_DMA_ISS_REQ4 13 /* S_DMA_12 */
326#define OMAP44XX_DMA_DSS_RFBI_REQ 14 /* S_DMA_13 */
327#define OMAP44XX_DMA_SPI3_TX0 15 /* S_DMA_14 */
328#define OMAP44XX_DMA_SPI3_RX0 16 /* S_DMA_15 */
329#define OMAP44XX_DMA_MCBSP2_TX 17 /* S_DMA_16 */
330#define OMAP44XX_DMA_MCBSP2_RX 18 /* S_DMA_17 */
331#define OMAP44XX_DMA_MCBSP3_TX 19 /* S_DMA_18 */
332#define OMAP44XX_DMA_MCBSP3_RX 20 /* S_DMA_19 */
333#define OMAP44XX_DMA_SPI3_TX1 23 /* S_DMA_22 */
334#define OMAP44XX_DMA_SPI3_RX1 24 /* S_DMA_23 */
335#define OMAP44XX_DMA_I2C3_TX 25 /* S_DMA_24 */
336#define OMAP44XX_DMA_I2C3_RX 26 /* S_DMA_25 */
337#define OMAP44XX_DMA_I2C1_TX 27 /* S_DMA_26 */
338#define OMAP44XX_DMA_I2C1_RX 28 /* S_DMA_27 */
339#define OMAP44XX_DMA_I2C2_TX 29 /* S_DMA_28 */
340#define OMAP44XX_DMA_I2C2_RX 30 /* S_DMA_29 */
341#define OMAP44XX_DMA_MCBSP4_TX 31 /* S_DMA_30 */
342#define OMAP44XX_DMA_MCBSP4_RX 32 /* S_DMA_31 */
343#define OMAP44XX_DMA_MCBSP1_TX 33 /* S_DMA_32 */
344#define OMAP44XX_DMA_MCBSP1_RX 34 /* S_DMA_33 */
345#define OMAP44XX_DMA_SPI1_TX0 35 /* S_DMA_34 */
346#define OMAP44XX_DMA_SPI1_RX0 36 /* S_DMA_35 */
347#define OMAP44XX_DMA_SPI1_TX1 37 /* S_DMA_36 */
348#define OMAP44XX_DMA_SPI1_RX1 38 /* S_DMA_37 */
349#define OMAP44XX_DMA_SPI1_TX2 39 /* S_DMA_38 */
350#define OMAP44XX_DMA_SPI1_RX2 40 /* S_DMA_39 */
351#define OMAP44XX_DMA_SPI1_TX3 41 /* S_DMA_40 */
352#define OMAP44XX_DMA_SPI1_RX3 42 /* S_DMA_41 */
353#define OMAP44XX_DMA_SPI2_TX0 43 /* S_DMA_42 */
354#define OMAP44XX_DMA_SPI2_RX0 44 /* S_DMA_43 */
355#define OMAP44XX_DMA_SPI2_TX1 45 /* S_DMA_44 */
356#define OMAP44XX_DMA_SPI2_RX1 46 /* S_DMA_45 */
357#define OMAP44XX_DMA_MMC2_TX 47 /* S_DMA_46 */
358#define OMAP44XX_DMA_MMC2_RX 48 /* S_DMA_47 */
359#define OMAP44XX_DMA_UART1_TX 49 /* S_DMA_48 */
360#define OMAP44XX_DMA_UART1_RX 50 /* S_DMA_49 */
361#define OMAP44XX_DMA_UART2_TX 51 /* S_DMA_50 */
362#define OMAP44XX_DMA_UART2_RX 52 /* S_DMA_51 */
363#define OMAP44XX_DMA_UART3_TX 53 /* S_DMA_52 */
364#define OMAP44XX_DMA_UART3_RX 54 /* S_DMA_53 */
365#define OMAP44XX_DMA_UART4_TX 55 /* S_DMA_54 */
366#define OMAP44XX_DMA_UART4_RX 56 /* S_DMA_55 */
367#define OMAP44XX_DMA_MMC4_TX 57 /* S_DMA_56 */
368#define OMAP44XX_DMA_MMC4_RX 58 /* S_DMA_57 */
369#define OMAP44XX_DMA_MMC5_TX 59 /* S_DMA_58 */
370#define OMAP44XX_DMA_MMC5_RX 60 /* S_DMA_59 */
371#define OMAP44XX_DMA_MMC1_TX 61 /* S_DMA_60 */
372#define OMAP44XX_DMA_MMC1_RX 62 /* S_DMA_61 */
373#define OMAP44XX_DMA_SYS_REQ3 64 /* S_DMA_63 */
374#define OMAP44XX_DMA_MCPDM_UP 65 /* S_DMA_64 */
375#define OMAP44XX_DMA_MCPDM_DL 66 /* S_DMA_65 */
376#define OMAP44XX_DMA_SPI4_TX0 70 /* S_DMA_69 */
377#define OMAP44XX_DMA_SPI4_RX0 71 /* S_DMA_70 */
378#define OMAP44XX_DMA_DSS_DSI1_REQ0 72 /* S_DMA_71 */
379#define OMAP44XX_DMA_DSS_DSI1_REQ1 73 /* S_DMA_72 */
380#define OMAP44XX_DMA_DSS_DSI1_REQ2 74 /* S_DMA_73 */
381#define OMAP44XX_DMA_DSS_DSI1_REQ3 75 /* S_DMA_74 */
382#define OMAP44XX_DMA_DSS_HDMI_REQ 76 /* S_DMA_75 */
383#define OMAP44XX_DMA_MMC3_TX 77 /* S_DMA_76 */
384#define OMAP44XX_DMA_MMC3_RX 78 /* S_DMA_77 */
385#define OMAP44XX_DMA_USIM_TX 79 /* S_DMA_78 */
386#define OMAP44XX_DMA_USIM_RX 80 /* S_DMA_79 */
387#define OMAP44XX_DMA_DSS_DSI2_REQ0 81 /* S_DMA_80 */
388#define OMAP44XX_DMA_DSS_DSI2_REQ1 82 /* S_DMA_81 */
389#define OMAP44XX_DMA_DSS_DSI2_REQ2 83 /* S_DMA_82 */
390#define OMAP44XX_DMA_DSS_DSI2_REQ3 84 /* S_DMA_83 */
391#define OMAP44XX_DMA_ABE_REQ0 101 /* S_DMA_100 */
392#define OMAP44XX_DMA_ABE_REQ1 102 /* S_DMA_101 */
393#define OMAP44XX_DMA_ABE_REQ2 103 /* S_DMA_102 */
394#define OMAP44XX_DMA_ABE_REQ3 104 /* S_DMA_103 */
395#define OMAP44XX_DMA_ABE_REQ4 105 /* S_DMA_104 */
396#define OMAP44XX_DMA_ABE_REQ5 106 /* S_DMA_105 */
397#define OMAP44XX_DMA_ABE_REQ6 107 /* S_DMA_106 */
398#define OMAP44XX_DMA_ABE_REQ7 108 /* S_DMA_107 */
399#define OMAP44XX_DMA_I2C4_TX 124 /* S_DMA_123 */
400#define OMAP44XX_DMA_I2C4_RX 125 /* S_DMA_124 */
401
314/*----------------------------------------------------------------------------*/ 402/*----------------------------------------------------------------------------*/
315 403
316/* Hardware registers for LCD DMA */ 404/* Hardware registers for LCD DMA */
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index bb154ea76769..e0d6eca222cc 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -53,6 +53,11 @@
53#define OMAP34XX_MCBSP4_BASE 0x49026000 53#define OMAP34XX_MCBSP4_BASE 0x49026000
54#define OMAP34XX_MCBSP5_BASE 0x48096000 54#define OMAP34XX_MCBSP5_BASE 0x48096000
55 55
56#define OMAP44XX_MCBSP1_BASE 0x49022000
57#define OMAP44XX_MCBSP2_BASE 0x49024000
58#define OMAP44XX_MCBSP3_BASE 0x49026000
59#define OMAP44XX_MCBSP4_BASE 0x48074000
60
56#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) 61#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
57 62
58#define OMAP_MCBSP_REG_DRR2 0x00 63#define OMAP_MCBSP_REG_DRR2 0x00
@@ -98,7 +103,8 @@
98#define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX 103#define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX
99#define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX 104#define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX
100 105
101#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) 106#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
107 defined(CONFIG_ARCH_OMAP4)
102 108
103#define OMAP_MCBSP_REG_DRR2 0x00 109#define OMAP_MCBSP_REG_DRR2 0x00
104#define OMAP_MCBSP_REG_DRR1 0x04 110#define OMAP_MCBSP_REG_DRR1 0x04
@@ -134,6 +140,11 @@
134#define OMAP_MCBSP_REG_XCERG 0x74 140#define OMAP_MCBSP_REG_XCERG 0x74
135#define OMAP_MCBSP_REG_XCERH 0x78 141#define OMAP_MCBSP_REG_XCERH 0x78
136#define OMAP_MCBSP_REG_SYSCON 0x8C 142#define OMAP_MCBSP_REG_SYSCON 0x8C
143#define OMAP_MCBSP_REG_THRSH2 0x90
144#define OMAP_MCBSP_REG_THRSH1 0x94
145#define OMAP_MCBSP_REG_IRQST 0xA0
146#define OMAP_MCBSP_REG_IRQEN 0xA4
147#define OMAP_MCBSP_REG_WAKEUPEN 0xA8
137#define OMAP_MCBSP_REG_XCCR 0xAC 148#define OMAP_MCBSP_REG_XCCR 0xAC
138#define OMAP_MCBSP_REG_RCCR 0xB0 149#define OMAP_MCBSP_REG_RCCR 0xB0
139 150
@@ -249,8 +260,27 @@
249#define RDISABLE 0x0001 260#define RDISABLE 0x0001
250 261
251/********************** McBSP SYSCONFIG bit definitions ********************/ 262/********************** McBSP SYSCONFIG bit definitions ********************/
263#define CLOCKACTIVITY(value) ((value)<<8)
264#define SIDLEMODE(value) ((value)<<3)
265#define ENAWAKEUP 0x0004
252#define SOFTRST 0x0002 266#define SOFTRST 0x0002
253 267
268/********************** McBSP DMA operating modes **************************/
269#define MCBSP_DMA_MODE_ELEMENT 0
270#define MCBSP_DMA_MODE_THRESHOLD 1
271#define MCBSP_DMA_MODE_FRAME 2
272
273/********************** McBSP WAKEUPEN bit definitions *********************/
274#define XEMPTYEOFEN 0x4000
275#define XRDYEN 0x0400
276#define XEOFEN 0x0200
277#define XFSXEN 0x0100
278#define XSYNCERREN 0x0080
279#define RRDYEN 0x0008
280#define REOFEN 0x0004
281#define RFSREN 0x0002
282#define RSYNCERREN 0x0001
283
254/* we don't do multichannel for now */ 284/* we don't do multichannel for now */
255struct omap_mcbsp_reg_cfg { 285struct omap_mcbsp_reg_cfg {
256 u16 spcr2; 286 u16 spcr2;
@@ -344,6 +374,9 @@ struct omap_mcbsp_platform_data {
344 u8 dma_rx_sync, dma_tx_sync; 374 u8 dma_rx_sync, dma_tx_sync;
345 u16 rx_irq, tx_irq; 375 u16 rx_irq, tx_irq;
346 struct omap_mcbsp_ops *ops; 376 struct omap_mcbsp_ops *ops;
377#ifdef CONFIG_ARCH_OMAP34XX
378 u16 buffer_size;
379#endif
347}; 380};
348 381
349struct omap_mcbsp { 382struct omap_mcbsp {
@@ -377,6 +410,11 @@ struct omap_mcbsp {
377 struct omap_mcbsp_platform_data *pdata; 410 struct omap_mcbsp_platform_data *pdata;
378 struct clk *iclk; 411 struct clk *iclk;
379 struct clk *fclk; 412 struct clk *fclk;
413#ifdef CONFIG_ARCH_OMAP34XX
414 int dma_op_mode;
415 u16 max_tx_thres;
416 u16 max_rx_thres;
417#endif
380}; 418};
381extern struct omap_mcbsp **mcbsp_ptr; 419extern struct omap_mcbsp **mcbsp_ptr;
382extern int omap_mcbsp_count; 420extern int omap_mcbsp_count;
@@ -385,10 +423,25 @@ int omap_mcbsp_init(void);
385void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, 423void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
386 int size); 424 int size);
387void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); 425void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
426#ifdef CONFIG_ARCH_OMAP34XX
427void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
428void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
429u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
430u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
431int omap_mcbsp_get_dma_op_mode(unsigned int id);
432#else
433static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
434{ }
435static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
436{ }
437static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
438static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
439static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
440#endif
388int omap_mcbsp_request(unsigned int id); 441int omap_mcbsp_request(unsigned int id);
389void omap_mcbsp_free(unsigned int id); 442void omap_mcbsp_free(unsigned int id);
390void omap_mcbsp_start(unsigned int id); 443void omap_mcbsp_start(unsigned int id, int tx, int rx);
391void omap_mcbsp_stop(unsigned int id); 444void omap_mcbsp_stop(unsigned int id, int tx, int rx);
392void omap_mcbsp_xmit_word(unsigned int id, u32 word); 445void omap_mcbsp_xmit_word(unsigned int id, u32 word);
393u32 omap_mcbsp_recv_word(unsigned int id); 446u32 omap_mcbsp_recv_word(unsigned int id);
394 447
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index efa0e0111f38..88ac9768f1c1 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -191,13 +191,177 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
191 OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); 191 OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
192 OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); 192 OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
193 OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); 193 OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
194 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 194 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
195 OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); 195 OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr);
196 OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); 196 OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr);
197 } 197 }
198} 198}
199EXPORT_SYMBOL(omap_mcbsp_config); 199EXPORT_SYMBOL(omap_mcbsp_config);
200 200
201#ifdef CONFIG_ARCH_OMAP34XX
202/*
203 * omap_mcbsp_set_tx_threshold configures how to deal
204 * with transmit threshold. the threshold value and handler can be
205 * configure in here.
206 */
207void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
208{
209 struct omap_mcbsp *mcbsp;
210 void __iomem *io_base;
211
212 if (!cpu_is_omap34xx())
213 return;
214
215 if (!omap_mcbsp_check_valid_id(id)) {
216 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
217 return;
218 }
219 mcbsp = id_to_mcbsp_ptr(id);
220 io_base = mcbsp->io_base;
221
222 OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
223}
224EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
225
226/*
227 * omap_mcbsp_set_rx_threshold configures how to deal
228 * with receive threshold. the threshold value and handler can be
229 * configure in here.
230 */
231void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
232{
233 struct omap_mcbsp *mcbsp;
234 void __iomem *io_base;
235
236 if (!cpu_is_omap34xx())
237 return;
238
239 if (!omap_mcbsp_check_valid_id(id)) {
240 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
241 return;
242 }
243 mcbsp = id_to_mcbsp_ptr(id);
244 io_base = mcbsp->io_base;
245
246 OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
247}
248EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
249
250/*
251 * omap_mcbsp_get_max_tx_thres just return the current configured
252 * maximum threshold for transmission
253 */
254u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
255{
256 struct omap_mcbsp *mcbsp;
257
258 if (!omap_mcbsp_check_valid_id(id)) {
259 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
260 return -ENODEV;
261 }
262 mcbsp = id_to_mcbsp_ptr(id);
263
264 return mcbsp->max_tx_thres;
265}
266EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
267
268/*
269 * omap_mcbsp_get_max_rx_thres just return the current configured
270 * maximum threshold for reception
271 */
272u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
273{
274 struct omap_mcbsp *mcbsp;
275
276 if (!omap_mcbsp_check_valid_id(id)) {
277 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
278 return -ENODEV;
279 }
280 mcbsp = id_to_mcbsp_ptr(id);
281
282 return mcbsp->max_rx_thres;
283}
284EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
285
286/*
287 * omap_mcbsp_get_dma_op_mode just return the current configured
288 * operating mode for the mcbsp channel
289 */
290int omap_mcbsp_get_dma_op_mode(unsigned int id)
291{
292 struct omap_mcbsp *mcbsp;
293 int dma_op_mode;
294
295 if (!omap_mcbsp_check_valid_id(id)) {
296 printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
297 return -ENODEV;
298 }
299 mcbsp = id_to_mcbsp_ptr(id);
300
301 spin_lock_irq(&mcbsp->lock);
302 dma_op_mode = mcbsp->dma_op_mode;
303 spin_unlock_irq(&mcbsp->lock);
304
305 return dma_op_mode;
306}
307EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
308
309static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
310{
311 /*
312 * Enable wakup behavior, smart idle and all wakeups
313 * REVISIT: some wakeups may be unnecessary
314 */
315 if (cpu_is_omap34xx()) {
316 u16 syscon;
317
318 syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
319 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
320
321 spin_lock_irq(&mcbsp->lock);
322 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
323 syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
324 CLOCKACTIVITY(0x02));
325 OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN,
326 XRDYEN | RRDYEN);
327 } else {
328 syscon |= SIDLEMODE(0x01);
329 }
330 spin_unlock_irq(&mcbsp->lock);
331
332 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
333 }
334}
335
336static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
337{
338 /*
339 * Disable wakup behavior, smart idle and all wakeups
340 */
341 if (cpu_is_omap34xx()) {
342 u16 syscon;
343
344 syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
345 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
346 /*
347 * HW bug workaround - If no_idle mode is taken, we need to
348 * go to smart_idle before going to always_idle, or the
349 * device will not hit retention anymore.
350 */
351 syscon |= SIDLEMODE(0x02);
352 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
353
354 syscon &= ~(SIDLEMODE(0x03));
355 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
356
357 OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);
358 }
359}
360#else
361static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
362static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
363#endif
364
201/* 365/*
202 * We can choose between IRQ based or polled IO. 366 * We can choose between IRQ based or polled IO.
203 * This needs to be called before omap_mcbsp_request(). 367 * This needs to be called before omap_mcbsp_request().
@@ -257,6 +421,9 @@ int omap_mcbsp_request(unsigned int id)
257 clk_enable(mcbsp->iclk); 421 clk_enable(mcbsp->iclk);
258 clk_enable(mcbsp->fclk); 422 clk_enable(mcbsp->fclk);
259 423
424 /* Do procedure specific to omap34xx arch, if applicable */
425 omap34xx_mcbsp_request(mcbsp);
426
260 /* 427 /*
261 * Make sure that transmitter, receiver and sample-rate generator are 428 * Make sure that transmitter, receiver and sample-rate generator are
262 * not running before activating IRQs. 429 * not running before activating IRQs.
@@ -305,6 +472,9 @@ void omap_mcbsp_free(unsigned int id)
305 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) 472 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
306 mcbsp->pdata->ops->free(id); 473 mcbsp->pdata->ops->free(id);
307 474
475 /* Do procedure specific to omap34xx arch, if applicable */
476 omap34xx_mcbsp_free(mcbsp);
477
308 clk_disable(mcbsp->fclk); 478 clk_disable(mcbsp->fclk);
309 clk_disable(mcbsp->iclk); 479 clk_disable(mcbsp->iclk);
310 480
@@ -328,14 +498,15 @@ void omap_mcbsp_free(unsigned int id)
328EXPORT_SYMBOL(omap_mcbsp_free); 498EXPORT_SYMBOL(omap_mcbsp_free);
329 499
330/* 500/*
331 * Here we start the McBSP, by enabling the sample 501 * Here we start the McBSP, by enabling transmitter, receiver or both.
332 * generator, both transmitter and receivers, 502 * If no transmitter or receiver is active prior calling, then sample-rate
333 * and the frame sync. 503 * generator and frame sync are started.
334 */ 504 */
335void omap_mcbsp_start(unsigned int id) 505void omap_mcbsp_start(unsigned int id, int tx, int rx)
336{ 506{
337 struct omap_mcbsp *mcbsp; 507 struct omap_mcbsp *mcbsp;
338 void __iomem *io_base; 508 void __iomem *io_base;
509 int idle;
339 u16 w; 510 u16 w;
340 511
341 if (!omap_mcbsp_check_valid_id(id)) { 512 if (!omap_mcbsp_check_valid_id(id)) {
@@ -348,32 +519,58 @@ void omap_mcbsp_start(unsigned int id)
348 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; 519 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
349 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; 520 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
350 521
351 /* Start the sample generator */ 522 idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
352 w = OMAP_MCBSP_READ(io_base, SPCR2); 523 OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
353 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6)); 524
525 if (idle) {
526 /* Start the sample generator */
527 w = OMAP_MCBSP_READ(io_base, SPCR2);
528 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
529 }
354 530
355 /* Enable transmitter and receiver */ 531 /* Enable transmitter and receiver */
532 tx &= 1;
356 w = OMAP_MCBSP_READ(io_base, SPCR2); 533 w = OMAP_MCBSP_READ(io_base, SPCR2);
357 OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1); 534 OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);
358 535
536 rx &= 1;
359 w = OMAP_MCBSP_READ(io_base, SPCR1); 537 w = OMAP_MCBSP_READ(io_base, SPCR1);
360 OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1); 538 OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx);
361 539
362 udelay(100); 540 /*
541 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
542 * REVISIT: 100us may give enough time for two CLKSRG, however
543 * due to some unknown PM related, clock gating etc. reason it
544 * is now at 500us.
545 */
546 udelay(500);
363 547
364 /* Start frame sync */ 548 if (idle) {
365 w = OMAP_MCBSP_READ(io_base, SPCR2); 549 /* Start frame sync */
366 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); 550 w = OMAP_MCBSP_READ(io_base, SPCR2);
551 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
552 }
553
554 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
555 /* Release the transmitter and receiver */
556 w = OMAP_MCBSP_READ(io_base, XCCR);
557 w &= ~(tx ? XDISABLE : 0);
558 OMAP_MCBSP_WRITE(io_base, XCCR, w);
559 w = OMAP_MCBSP_READ(io_base, RCCR);
560 w &= ~(rx ? RDISABLE : 0);
561 OMAP_MCBSP_WRITE(io_base, RCCR, w);
562 }
367 563
368 /* Dump McBSP Regs */ 564 /* Dump McBSP Regs */
369 omap_mcbsp_dump_reg(id); 565 omap_mcbsp_dump_reg(id);
370} 566}
371EXPORT_SYMBOL(omap_mcbsp_start); 567EXPORT_SYMBOL(omap_mcbsp_start);
372 568
373void omap_mcbsp_stop(unsigned int id) 569void omap_mcbsp_stop(unsigned int id, int tx, int rx)
374{ 570{
375 struct omap_mcbsp *mcbsp; 571 struct omap_mcbsp *mcbsp;
376 void __iomem *io_base; 572 void __iomem *io_base;
573 int idle;
377 u16 w; 574 u16 w;
378 575
379 if (!omap_mcbsp_check_valid_id(id)) { 576 if (!omap_mcbsp_check_valid_id(id)) {
@@ -385,16 +582,33 @@ void omap_mcbsp_stop(unsigned int id)
385 io_base = mcbsp->io_base; 582 io_base = mcbsp->io_base;
386 583
387 /* Reset transmitter */ 584 /* Reset transmitter */
585 tx &= 1;
586 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
587 w = OMAP_MCBSP_READ(io_base, XCCR);
588 w |= (tx ? XDISABLE : 0);
589 OMAP_MCBSP_WRITE(io_base, XCCR, w);
590 }
388 w = OMAP_MCBSP_READ(io_base, SPCR2); 591 w = OMAP_MCBSP_READ(io_base, SPCR2);
389 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); 592 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx);
390 593
391 /* Reset receiver */ 594 /* Reset receiver */
595 rx &= 1;
596 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
597 w = OMAP_MCBSP_READ(io_base, RCCR);
598 w |= (tx ? RDISABLE : 0);
599 OMAP_MCBSP_WRITE(io_base, RCCR, w);
600 }
392 w = OMAP_MCBSP_READ(io_base, SPCR1); 601 w = OMAP_MCBSP_READ(io_base, SPCR1);
393 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1)); 602 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx);
394 603
395 /* Reset the sample rate generator */ 604 idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
396 w = OMAP_MCBSP_READ(io_base, SPCR2); 605 OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
397 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); 606
607 if (idle) {
608 /* Reset the sample rate generator */
609 w = OMAP_MCBSP_READ(io_base, SPCR2);
610 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
611 }
398} 612}
399EXPORT_SYMBOL(omap_mcbsp_stop); 613EXPORT_SYMBOL(omap_mcbsp_stop);
400 614
@@ -883,6 +1097,149 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
883} 1097}
884EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); 1098EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
885 1099
1100#ifdef CONFIG_ARCH_OMAP34XX
1101#define max_thres(m) (mcbsp->pdata->buffer_size)
1102#define valid_threshold(m, val) ((val) <= max_thres(m))
1103#define THRESHOLD_PROP_BUILDER(prop) \
1104static ssize_t prop##_show(struct device *dev, \
1105 struct device_attribute *attr, char *buf) \
1106{ \
1107 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
1108 \
1109 return sprintf(buf, "%u\n", mcbsp->prop); \
1110} \
1111 \
1112static ssize_t prop##_store(struct device *dev, \
1113 struct device_attribute *attr, \
1114 const char *buf, size_t size) \
1115{ \
1116 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
1117 unsigned long val; \
1118 int status; \
1119 \
1120 status = strict_strtoul(buf, 0, &val); \
1121 if (status) \
1122 return status; \
1123 \
1124 if (!valid_threshold(mcbsp, val)) \
1125 return -EDOM; \
1126 \
1127 mcbsp->prop = val; \
1128 return size; \
1129} \
1130 \
1131static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
1132
1133THRESHOLD_PROP_BUILDER(max_tx_thres);
1134THRESHOLD_PROP_BUILDER(max_rx_thres);
1135
1136static const char *dma_op_modes[] = {
1137 "element", "threshold", "frame",
1138};
1139
1140static ssize_t dma_op_mode_show(struct device *dev,
1141 struct device_attribute *attr, char *buf)
1142{
1143 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1144 int dma_op_mode, i = 0;
1145 ssize_t len = 0;
1146 const char * const *s;
1147
1148 spin_lock_irq(&mcbsp->lock);
1149 dma_op_mode = mcbsp->dma_op_mode;
1150 spin_unlock_irq(&mcbsp->lock);
1151
1152 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
1153 if (dma_op_mode == i)
1154 len += sprintf(buf + len, "[%s] ", *s);
1155 else
1156 len += sprintf(buf + len, "%s ", *s);
1157 }
1158 len += sprintf(buf + len, "\n");
1159
1160 return len;
1161}
1162
1163static ssize_t dma_op_mode_store(struct device *dev,
1164 struct device_attribute *attr,
1165 const char *buf, size_t size)
1166{
1167 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1168 const char * const *s;
1169 int i = 0;
1170
1171 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
1172 if (sysfs_streq(buf, *s))
1173 break;
1174
1175 if (i == ARRAY_SIZE(dma_op_modes))
1176 return -EINVAL;
1177
1178 spin_lock_irq(&mcbsp->lock);
1179 if (!mcbsp->free) {
1180 size = -EBUSY;
1181 goto unlock;
1182 }
1183 mcbsp->dma_op_mode = i;
1184
1185unlock:
1186 spin_unlock_irq(&mcbsp->lock);
1187
1188 return size;
1189}
1190
1191static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1192
1193static const struct attribute *additional_attrs[] = {
1194 &dev_attr_max_tx_thres.attr,
1195 &dev_attr_max_rx_thres.attr,
1196 &dev_attr_dma_op_mode.attr,
1197 NULL,
1198};
1199
1200static const struct attribute_group additional_attr_group = {
1201 .attrs = (struct attribute **)additional_attrs,
1202};
1203
1204static inline int __devinit omap_additional_add(struct device *dev)
1205{
1206 return sysfs_create_group(&dev->kobj, &additional_attr_group);
1207}
1208
1209static inline void __devexit omap_additional_remove(struct device *dev)
1210{
1211 sysfs_remove_group(&dev->kobj, &additional_attr_group);
1212}
1213
1214static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1215{
1216 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1217 if (cpu_is_omap34xx()) {
1218 mcbsp->max_tx_thres = max_thres(mcbsp);
1219 mcbsp->max_rx_thres = max_thres(mcbsp);
1220 /*
1221 * REVISIT: Set dmap_op_mode to THRESHOLD as default
1222 * for mcbsp2 instances.
1223 */
1224 if (omap_additional_add(mcbsp->dev))
1225 dev_warn(mcbsp->dev,
1226 "Unable to create additional controls\n");
1227 } else {
1228 mcbsp->max_tx_thres = -EINVAL;
1229 mcbsp->max_rx_thres = -EINVAL;
1230 }
1231}
1232
1233static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
1234{
1235 if (cpu_is_omap34xx())
1236 omap_additional_remove(mcbsp->dev);
1237}
1238#else
1239static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
1240static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
1241#endif /* CONFIG_ARCH_OMAP34XX */
1242
886/* 1243/*
887 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. 1244 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
888 * 730 has only 2 McBSP, and both of them are MPU peripherals. 1245 * 730 has only 2 McBSP, and both of them are MPU peripherals.
@@ -953,6 +1310,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
953 mcbsp->dev = &pdev->dev; 1310 mcbsp->dev = &pdev->dev;
954 mcbsp_ptr[id] = mcbsp; 1311 mcbsp_ptr[id] = mcbsp;
955 platform_set_drvdata(pdev, mcbsp); 1312 platform_set_drvdata(pdev, mcbsp);
1313
1314 /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
1315 omap34xx_device_init(mcbsp);
1316
956 return 0; 1317 return 0;
957 1318
958err_fclk: 1319err_fclk:
@@ -976,6 +1337,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
976 mcbsp->pdata->ops->free) 1337 mcbsp->pdata->ops->free)
977 mcbsp->pdata->ops->free(mcbsp->id); 1338 mcbsp->pdata->ops->free(mcbsp->id);
978 1339
1340 omap34xx_device_exit(mcbsp);
1341
979 clk_disable(mcbsp->fclk); 1342 clk_disable(mcbsp->fclk);
980 clk_disable(mcbsp->iclk); 1343 clk_disable(mcbsp->iclk);
981 clk_put(mcbsp->fclk); 1344 clk_put(mcbsp->fclk);
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index 935c7558469b..8931c5f0e46b 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -198,4 +198,9 @@ config S3C_DEV_USB_HSOTG
198 help 198 help
199 Compile in platform device definition for USB high-speed OtG 199 Compile in platform device definition for USB high-speed OtG
200 200
201config S3C_DEV_NAND
202 bool
203 help
204 Compile in platform device definition for NAND controller
205
201endif 206endif
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 0761766b1833..3c09109e9e84 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -28,13 +28,17 @@ obj-$(CONFIG_PM) += pm.o
28obj-$(CONFIG_PM) += pm-gpio.o 28obj-$(CONFIG_PM) += pm-gpio.o
29obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o 29obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o
30 30
31# PWM support
32
33obj-$(CONFIG_HAVE_PWM) += pwm.o
34
31# devices 35# devices
32 36
33obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o 37obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
34obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o 38obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
35obj-y += dev-i2c0.o 39obj-y += dev-i2c0.o
36obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o 40obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
37obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += dev-audio.o
38obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o 41obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
39obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o 42obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
40obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o 43obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
44obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
diff --git a/arch/arm/plat-s3c/dev-nand.c b/arch/arm/plat-s3c/dev-nand.c
new file mode 100644
index 000000000000..4e5323732434
--- /dev/null
+++ b/arch/arm/plat-s3c/dev-nand.c
@@ -0,0 +1,30 @@
1/*
2 * S3C series device definition for nand device
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7*/
8
9#include <linux/kernel.h>
10#include <linux/platform_device.h>
11
12#include <mach/map.h>
13#include <plat/devs.h>
14
15static struct resource s3c_nand_resource[] = {
16 [0] = {
17 .start = S3C_PA_NAND,
18 .end = S3C_PA_NAND + SZ_1M,
19 .flags = IORESOURCE_MEM,
20 }
21};
22
23struct platform_device s3c_device_nand = {
24 .name = "s3c2410-nand",
25 .id = -1,
26 .num_resources = ARRAY_SIZE(s3c_nand_resource),
27 .resource = s3c_nand_resource,
28};
29
30EXPORT_SYMBOL(s3c_device_nand);
diff --git a/arch/arm/plat-s3c/include/plat/adc.h b/arch/arm/plat-s3c/include/plat/adc.h
index d847bd476b6c..5f3b1cd53b90 100644
--- a/arch/arm/plat-s3c/include/plat/adc.h
+++ b/arch/arm/plat-s3c/include/plat/adc.h
@@ -19,10 +19,14 @@ struct s3c_adc_client;
19extern int s3c_adc_start(struct s3c_adc_client *client, 19extern int s3c_adc_start(struct s3c_adc_client *client,
20 unsigned int channel, unsigned int nr_samples); 20 unsigned int channel, unsigned int nr_samples);
21 21
22extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
23
22extern struct s3c_adc_client * 24extern struct s3c_adc_client *
23 s3c_adc_register(struct platform_device *pdev, 25 s3c_adc_register(struct platform_device *pdev,
24 void (*select)(unsigned selected), 26 void (*select)(struct s3c_adc_client *client,
25 void (*conv)(unsigned d0, unsigned d1, 27 unsigned selected),
28 void (*conv)(struct s3c_adc_client *client,
29 unsigned d0, unsigned d1,
26 unsigned *samples_left), 30 unsigned *samples_left),
27 unsigned int is_ts); 31 unsigned int is_ts);
28 32
diff --git a/arch/arm/plat-s3c/include/plat/audio-simtec.h b/arch/arm/plat-s3c/include/plat/audio-simtec.h
new file mode 100644
index 000000000000..0f440b9168db
--- /dev/null
+++ b/arch/arm/plat-s3c/include/plat/audio-simtec.h
@@ -0,0 +1,37 @@
1/* arch/arm/plat-s3c/include/plat/audio-simtec.h
2 *
3 * Copyright 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Simtec Audio support.
12*/
13
14/**
15 * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
16 * @use_mpllin: Select codec clock from MPLLin
17 * @output_cdclk: Need to output CDCLK to the codec
18 * @have_mic: Set if we have a MIC socket
19 * @have_lout: Set if we have a LineOut socket
20 * @amp_gpio: GPIO pin to enable the AMP
21 * @amp_gain: Option GPIO to control AMP gain
22 */
23struct s3c24xx_audio_simtec_pdata {
24 unsigned int use_mpllin:1;
25 unsigned int output_cdclk:1;
26
27 unsigned int have_mic:1;
28 unsigned int have_lout:1;
29
30 int amp_gpio;
31 int amp_gain[2];
32
33 void (*startup)(void);
34};
35
36extern int simtec_audio_add(const char *codec_name,
37 struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-s3c/include/plat/cpu-freq.h b/arch/arm/plat-s3c/include/plat/cpu-freq.h
index c86a13307e90..7b982b7f28cd 100644
--- a/arch/arm/plat-s3c/include/plat/cpu-freq.h
+++ b/arch/arm/plat-s3c/include/plat/cpu-freq.h
@@ -17,6 +17,21 @@ struct s3c_cpufreq_info;
17struct s3c_cpufreq_board; 17struct s3c_cpufreq_board;
18struct s3c_iotimings; 18struct s3c_iotimings;
19 19
20/**
21 * struct s3c_freq - frequency information (mainly for core drivers)
22 * @fclk: The FCLK frequency in Hz.
23 * @armclk: The ARMCLK frequency in Hz.
24 * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
25 * @hclk: The HCLK frequency in Hz.
26 * @pclk: The PCLK frequency in Hz.
27 *
28 * This contains the frequency information about the current configuration
29 * mainly for the core drivers to ensure we do not end up passing about
30 * a large number of parameters.
31 *
32 * The @hclk_tns field is a useful cache for the parts of the drivers that
33 * need to calculate IO timings and suchlike.
34 */
20struct s3c_freq { 35struct s3c_freq {
21 unsigned long fclk; 36 unsigned long fclk;
22 unsigned long armclk; 37 unsigned long armclk;
@@ -25,48 +40,84 @@ struct s3c_freq {
25 unsigned long pclk; 40 unsigned long pclk;
26}; 41};
27 42
28/* wrapper 'struct cpufreq_freqs' so that any drivers receiving the 43/**
44 * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
45 * @freqs: The cpufreq setting information.
46 * @old: The old clock settings.
47 * @new: The new clock settings.
48 * @pll_changing: Set if the PLL is changing.
49 *
50 * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
29 * notification can use this information that is not provided by just 51 * notification can use this information that is not provided by just
30 * having the core frequency alone. 52 * having the core frequency alone.
53 *
54 * The pll_changing flag is used to indicate if the PLL itself is
55 * being set during this change. This is important as the clocks
56 * will temporarily be set to the XTAL clock during this time, so
57 * drivers may want to close down their output during this time.
58 *
59 * Note, this is not being used by any current drivers and therefore
60 * may be removed in the future.
31 */ 61 */
32
33struct s3c_cpufreq_freqs { 62struct s3c_cpufreq_freqs {
34 struct cpufreq_freqs freqs; 63 struct cpufreq_freqs freqs;
35 struct s3c_freq old; 64 struct s3c_freq old;
36 struct s3c_freq new; 65 struct s3c_freq new;
66
67 unsigned int pll_changing:1;
37}; 68};
38 69
39#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs) 70#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
40 71
72/**
73 * struct s3c_clkdivs - clock divisor information
74 * @p_divisor: Divisor from FCLK to PCLK.
75 * @h_divisor: Divisor from FCLK to HCLK.
76 * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
77 * @dvs: Non-zero if using DVS mode for ARMCLK.
78 *
79 * Divisor settings for the core clocks.
80 */
41struct s3c_clkdivs { 81struct s3c_clkdivs {
42 int p_divisor; /* fclk / pclk */ 82 int p_divisor;
43 int h_divisor; /* fclk / hclk */ 83 int h_divisor;
44 int arm_divisor; /* not all cpus have this. */ 84 int arm_divisor;
45 unsigned char dvs; /* using dvs mode to arm. */ 85 unsigned char dvs;
46}; 86};
47 87
48#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s)) 88#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
49 89
90/**
91 * struct s3c_pllval - PLL value entry.
92 * @freq: The frequency for this entry in Hz.
93 * @pll_reg: The PLL register setting for this PLL value.
94 */
50struct s3c_pllval { 95struct s3c_pllval {
51 unsigned long freq; 96 unsigned long freq;
52 unsigned long pll_reg; 97 unsigned long pll_reg;
53}; 98};
54 99
55struct s3c_cpufreq_config { 100/**
56 struct s3c_freq freq; 101 * struct s3c_cpufreq_board - per-board cpu frequency informatin
57 struct s3c_pllval pll; 102 * @refresh: The SDRAM refresh period in nanoseconds.
58 struct s3c_clkdivs divs; 103 * @auto_io: Set if the IO timing settings should be generated from the
59 struct s3c_cpufreq_info *info; /* for core, not drivers */ 104 * initialisation time hardware registers.
60 struct s3c_cpufreq_board *board; 105 * @need_io: Set if the board has external IO on any of the chipselect
61}; 106 * lines that will require the hardware timing registers to be
62 107 * updated on a clock change.
63/* s3c_cpufreq_board 108 * @max: The maxium frequency limits for the system. Any field that
109 * is left at zero will use the CPU's settings.
110 *
111 * This contains the board specific settings that affect how the CPU
112 * drivers chose settings. These include the memory refresh and IO
113 * timing information.
64 * 114 *
65 * per-board configuraton information, such as memory refresh and 115 * Registration depends on the driver being used, the ARMCLK only
66 * how to initialise IO timings. 116 * implementation does not currently need this but the older style
117 * driver requires this to be available.
67 */ 118 */
68struct s3c_cpufreq_board { 119struct s3c_cpufreq_board {
69 unsigned int refresh; /* refresh period in ns */ 120 unsigned int refresh;
70 unsigned int auto_io:1; /* automatically init io timings. */ 121 unsigned int auto_io:1; /* automatically init io timings. */
71 unsigned int need_io:1; /* set if needs io timing support. */ 122 unsigned int need_io:1; /* set if needs io timing support. */
72 123
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
index be541cbba070..fbc3d498e02e 100644
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ b/arch/arm/plat-s3c/include/plat/cpu.h
@@ -65,6 +65,7 @@ extern struct sys_timer s3c24xx_timer;
65/* system device classes */ 65/* system device classes */
66 66
67extern struct sysdev_class s3c2410_sysclass; 67extern struct sysdev_class s3c2410_sysclass;
68extern struct sysdev_class s3c2410a_sysclass;
68extern struct sysdev_class s3c2412_sysclass; 69extern struct sysdev_class s3c2412_sysclass;
69extern struct sysdev_class s3c2440_sysclass; 70extern struct sysdev_class s3c2440_sysclass;
70extern struct sysdev_class s3c2442_sysclass; 71extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h
index 2e170827e0b0..0f540ea1e999 100644
--- a/arch/arm/plat-s3c/include/plat/devs.h
+++ b/arch/arm/plat-s3c/include/plat/devs.h
@@ -46,6 +46,8 @@ extern struct platform_device s3c_device_hsmmc2;
46extern struct platform_device s3c_device_spi0; 46extern struct platform_device s3c_device_spi0;
47extern struct platform_device s3c_device_spi1; 47extern struct platform_device s3c_device_spi1;
48 48
49extern struct platform_device s3c_device_hwmon;
50
49extern struct platform_device s3c_device_nand; 51extern struct platform_device s3c_device_nand;
50 52
51extern struct platform_device s3c_device_usbgadget; 53extern struct platform_device s3c_device_usbgadget;
@@ -56,5 +58,6 @@ extern struct platform_device s3c_device_usb_hsotg;
56#ifdef CONFIG_CPU_S3C2440 58#ifdef CONFIG_CPU_S3C2440
57 59
58extern struct platform_device s3c_device_camif; 60extern struct platform_device s3c_device_camif;
61extern struct platform_device s3c_device_ac97;
59 62
60#endif 63#endif
diff --git a/arch/arm/plat-s3c/include/plat/hwmon.h b/arch/arm/plat-s3c/include/plat/hwmon.h
new file mode 100644
index 000000000000..1ba88ea0aa31
--- /dev/null
+++ b/arch/arm/plat-s3c/include/plat/hwmon.h
@@ -0,0 +1,41 @@
1/* linux/arch/arm/plat-s3c/include/plat/hwmon.h
2 *
3 * Copyright 2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C - HWMon interface for ADC
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#ifndef __ASM_ARCH_ADC_HWMON_H
15#define __ASM_ARCH_ADC_HWMON_H __FILE__
16
17/**
18 * s3c_hwmon_chcfg - channel configuration
19 * @name: The name to give this channel.
20 * @mult: Multiply the ADC value read by this.
21 * @div: Divide the value from the ADC by this.
22 *
23 * The value read from the ADC is converted to a value that
24 * hwmon expects (mV) by result = (value_read * @mult) / @div.
25 */
26struct s3c_hwmon_chcfg {
27 const char *name;
28 unsigned int mult;
29 unsigned int div;
30};
31
32/**
33 * s3c_hwmon_pdata - HWMON platform data
34 * @in: One configuration for each possible channel used.
35 */
36struct s3c_hwmon_pdata {
37 struct s3c_hwmon_chcfg *in[8];
38};
39
40#endif /* __ASM_ARCH_ADC_HWMON_H */
41
diff --git a/arch/arm/plat-s3c/include/plat/map-base.h b/arch/arm/plat-s3c/include/plat/map-base.h
index b84289d32a54..250be311c85b 100644
--- a/arch/arm/plat-s3c/include/plat/map-base.h
+++ b/arch/arm/plat-s3c/include/plat/map-base.h
@@ -32,9 +32,15 @@
32 32
33#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */ 33#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */
34#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */ 34#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */
35#define S3C_VA_MEM S3C_ADDR(0x00200000) /* system control */ 35#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
36#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */ 36#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
37#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */ 37#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
38#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */ 38#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
39 39
40/* This is used for the CPU specific mappings that may be needed, so that
41 * they do not need to directly used S3C_ADDR() and thus make it easier to
42 * modify the space for mapping.
43 */
44#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x))
45
40#endif /* __ASM_PLAT_MAP_H */ 46#endif /* __ASM_PLAT_MAP_H */
diff --git a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
index 0fad7571030e..07659dad1748 100644
--- a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
+++ b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
@@ -33,6 +33,11 @@
33#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) 33#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
34#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) 34#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
35 35
36#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
37#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
38#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
39#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
40
36#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) 41#define S3C64XX_IISMOD_IMS_PCLK (0 << 10)
37#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) 42#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10)
38 43
diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c/pwm.c
index 82a6d4de02a3..4fdc5b307fd2 100644
--- a/arch/arm/plat-s3c24xx/pwm.c
+++ b/arch/arm/plat-s3c/pwm.c
@@ -1,10 +1,10 @@
1/* arch/arm/plat-s3c24xx/pwm.c 1/* arch/arm/plat-s3c/pwm.c
2 * 2 *
3 * Copyright (c) 2007 Ben Dooks 3 * Copyright (c) 2007 Ben Dooks
4 * Copyright (c) 2008 Simtec Electronics 4 * Copyright (c) 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> 5 * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
6 * 6 *
7 * S3C24XX PWM device core 7 * S3C series PWM device core
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
20#include <linux/pwm.h> 20#include <linux/pwm.h>
21 21
22#include <mach/irqs.h> 22#include <mach/irqs.h>
23#include <mach/map.h>
23 24
24#include <plat/devs.h> 25#include <plat/devs.h>
25#include <plat/regs-timer.h> 26#include <plat/regs-timer.h>
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 5b0bc914f58e..9c7aca489643 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -10,6 +10,7 @@ config PLAT_S3C24XX
10 default y 10 default y
11 select NO_IOPORT 11 select NO_IOPORT
12 select ARCH_REQUIRE_GPIOLIB 12 select ARCH_REQUIRE_GPIOLIB
13 select S3C_DEVICE_NAND
13 help 14 help
14 Base platform code for any Samsung S3C24XX device 15 Base platform code for any Samsung S3C24XX device
15 16
@@ -34,6 +35,40 @@ config CPU_S3C244X
34 help 35 help
35 Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. 36 Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
36 37
38config S3C2440_CPUFREQ
39 bool "S3C2440/S3C2442 CPU Frequency scaling support"
40 depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
41 select S3C2410_CPUFREQ_UTILS
42 default y
43 help
44 CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
45
46config S3C2440_XTAL_12000000
47 bool
48 help
49 Indicate that the build needs to support 12MHz system
50 crystal.
51
52config S3C2440_XTAL_16934400
53 bool
54 help
55 Indicate that the build needs to support 16.9344MHz system
56 crystal.
57
58config S3C2440_PLL_12000000
59 bool
60 depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
61 default y if CPU_FREQ_S3C24XX_PLL
62 help
63 PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
64
65config S3C2440_PLL_16934400
66 bool
67 depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
68 default y if CPU_FREQ_S3C24XX_PLL
69 help
70 PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
71
37config S3C24XX_PWM 72config S3C24XX_PWM
38 bool "PWM device support" 73 bool "PWM device support"
39 select HAVE_PWM 74 select HAVE_PWM
@@ -105,8 +140,39 @@ config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
105 SPI GPIO configuration code for BUS 1 when connected to 140 SPI GPIO configuration code for BUS 1 when connected to
106 GPG5, GPG6 and GPG7. 141 GPG5, GPG6 and GPG7.
107 142
143config S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10
144 bool
145 help
146 SPI GPIO configuration code for BUS 1 when connected to
147 GPD8, GPD9 and GPD10.
148
108# common code for s3c24xx based machines, such as the SMDKs. 149# common code for s3c24xx based machines, such as the SMDKs.
109 150
151# cpu frequency items common between s3c2410 and s3c2440/s3c2442
152
153config S3C2410_IOTIMING
154 bool
155 depends on CPU_FREQ_S3C24XX
156 help
157 Internal node to select io timing code that is common to the s3c2410
158 and s3c2440/s3c2442 cpu frequency support.
159
160config S3C2410_CPUFREQ_UTILS
161 bool
162 depends on CPU_FREQ_S3C24XX
163 help
164 Internal node to select timing code that is common to the s3c2410
165 and s3c2440/s3c244 cpu frequency support.
166
167# cpu frequency support common to s3c2412, s3c2413 and s3c2442
168
169config S3C2412_IOTIMING
170 bool
171 depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443)
172 help
173 Intel node to select io timing code that is common to the s3c2412
174 and the s3c2443.
175
110config MACH_SMDK 176config MACH_SMDK
111 bool 177 bool
112 help 178 help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 579a165c2827..7780d2dd833a 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -20,19 +20,28 @@ obj-y += gpiolib.o
20obj-y += clock.o 20obj-y += clock.o
21obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o 21obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o
22 22
23obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o
24obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
25
23# Architecture dependant builds 26# Architecture dependant builds
24 27
25obj-$(CONFIG_CPU_S3C244X) += s3c244x.o 28obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
26obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o 29obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
27obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o 30obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
31obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o
32obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
33obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
34
28obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o 35obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
29obj-$(CONFIG_PM) += pm.o 36obj-$(CONFIG_PM) += pm.o
30obj-$(CONFIG_PM) += irq-pm.o 37obj-$(CONFIG_PM) += irq-pm.o
31obj-$(CONFIG_PM) += sleep.o 38obj-$(CONFIG_PM) += sleep.o
32obj-$(CONFIG_S3C24XX_PWM) += pwm.o
33obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o 39obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
34obj-$(CONFIG_S3C2410_DMA) += dma.o 40obj-$(CONFIG_S3C2410_DMA) += dma.o
35obj-$(CONFIG_S3C24XX_ADC) += adc.o 41obj-$(CONFIG_S3C24XX_ADC) += adc.o
42obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
43obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
44obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
36 45
37# device specific setup and/or initialisation 46# device specific setup and/or initialisation
38obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o 47obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o
@@ -41,6 +50,7 @@ obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o
41 50
42obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o 51obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o
43obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7) += spi-bus1-gpg5_6_7.o 52obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7) += spi-bus1-gpg5_6_7.o
53obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10) += spi-bus1-gpd8_9_10.o
44 54
45# machine common support 55# machine common support
46 56
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c
index ee1baf11ad9e..11117a7ba911 100644
--- a/arch/arm/plat-s3c24xx/adc.c
+++ b/arch/arm/plat-s3c24xx/adc.c
@@ -39,13 +39,16 @@
39struct s3c_adc_client { 39struct s3c_adc_client {
40 struct platform_device *pdev; 40 struct platform_device *pdev;
41 struct list_head pend; 41 struct list_head pend;
42 wait_queue_head_t *wait;
42 43
43 unsigned int nr_samples; 44 unsigned int nr_samples;
45 int result;
44 unsigned char is_ts; 46 unsigned char is_ts;
45 unsigned char channel; 47 unsigned char channel;
46 48
47 void (*select_cb)(unsigned selected); 49 void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
48 void (*convert_cb)(unsigned val1, unsigned val2, 50 void (*convert_cb)(struct s3c_adc_client *c,
51 unsigned val1, unsigned val2,
49 unsigned *samples_left); 52 unsigned *samples_left);
50}; 53};
51 54
@@ -81,7 +84,7 @@ static inline void s3c_adc_select(struct adc_device *adc,
81{ 84{
82 unsigned con = readl(adc->regs + S3C2410_ADCCON); 85 unsigned con = readl(adc->regs + S3C2410_ADCCON);
83 86
84 client->select_cb(1); 87 client->select_cb(client, 1);
85 88
86 con &= ~S3C2410_ADCCON_MUXMASK; 89 con &= ~S3C2410_ADCCON_MUXMASK;
87 con &= ~S3C2410_ADCCON_STDBM; 90 con &= ~S3C2410_ADCCON_STDBM;
@@ -153,25 +156,61 @@ int s3c_adc_start(struct s3c_adc_client *client,
153} 156}
154EXPORT_SYMBOL_GPL(s3c_adc_start); 157EXPORT_SYMBOL_GPL(s3c_adc_start);
155 158
156static void s3c_adc_default_select(unsigned select) 159static void s3c_convert_done(struct s3c_adc_client *client,
160 unsigned v, unsigned u, unsigned *left)
161{
162 client->result = v;
163 wake_up(client->wait);
164}
165
166int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
167{
168 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
169 int ret;
170
171 client->convert_cb = s3c_convert_done;
172 client->wait = &wake;
173 client->result = -1;
174
175 ret = s3c_adc_start(client, ch, 1);
176 if (ret < 0)
177 goto err;
178
179 ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
180 if (client->result < 0) {
181 ret = -ETIMEDOUT;
182 goto err;
183 }
184
185 client->convert_cb = NULL;
186 return client->result;
187
188err:
189 return ret;
190}
191EXPORT_SYMBOL_GPL(s3c_adc_convert);
192
193static void s3c_adc_default_select(struct s3c_adc_client *client,
194 unsigned select)
157{ 195{
158} 196}
159 197
160struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, 198struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
161 void (*select)(unsigned int selected), 199 void (*select)(struct s3c_adc_client *client,
162 void (*conv)(unsigned d0, unsigned d1, 200 unsigned int selected),
201 void (*conv)(struct s3c_adc_client *client,
202 unsigned d0, unsigned d1,
163 unsigned *samples_left), 203 unsigned *samples_left),
164 unsigned int is_ts) 204 unsigned int is_ts)
165{ 205{
166 struct s3c_adc_client *client; 206 struct s3c_adc_client *client;
167 207
168 WARN_ON(!pdev); 208 WARN_ON(!pdev);
169 WARN_ON(!conv);
170 209
171 if (!select) 210 if (!select)
172 select = s3c_adc_default_select; 211 select = s3c_adc_default_select;
173 212
174 if (!conv || !pdev) 213 if (!pdev)
175 return ERR_PTR(-EINVAL); 214 return ERR_PTR(-EINVAL);
176 215
177 client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL); 216 client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
@@ -230,16 +269,19 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
230 adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); 269 adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
231 270
232 client->nr_samples--; 271 client->nr_samples--;
233 (client->convert_cb)(data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples); 272
273 if (client->convert_cb)
274 (client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff,
275 &client->nr_samples);
234 276
235 if (client->nr_samples > 0) { 277 if (client->nr_samples > 0) {
236 /* fire another conversion for this */ 278 /* fire another conversion for this */
237 279
238 client->select_cb(1); 280 client->select_cb(client, 1);
239 s3c_adc_convert(adc); 281 s3c_adc_convert(adc);
240 } else { 282 } else {
241 local_irq_save(flags); 283 local_irq_save(flags);
242 (client->select_cb)(0); 284 (client->select_cb)(client, 0);
243 adc->cur = NULL; 285 adc->cur = NULL;
244 286
245 s3c_adc_try(adc); 287 s3c_adc_try(adc);
diff --git a/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
new file mode 100644
index 000000000000..a9276667c2fb
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
@@ -0,0 +1,199 @@
1/* linux/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
2 *
3 * Copyright (c) 2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C24XX CPU Frequency scaling - debugfs status support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/cpufreq.h>
19#include <linux/debugfs.h>
20#include <linux/seq_file.h>
21#include <linux/err.h>
22
23#include <plat/cpu-freq-core.h>
24
25static struct dentry *dbgfs_root;
26static struct dentry *dbgfs_file_io;
27static struct dentry *dbgfs_file_info;
28static struct dentry *dbgfs_file_board;
29
30#define print_ns(x) ((x) / 10), ((x) % 10)
31
32static void show_max(struct seq_file *seq, struct s3c_freq *f)
33{
34 seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n",
35 f->fclk, f->hclk, f->pclk, f->armclk);
36}
37
38static int board_show(struct seq_file *seq, void *p)
39{
40 struct s3c_cpufreq_config *cfg;
41 struct s3c_cpufreq_board *brd;
42
43 cfg = s3c_cpufreq_getconfig();
44 if (!cfg) {
45 seq_printf(seq, "no configuration registered\n");
46 return 0;
47 }
48
49 brd = cfg->board;
50 if (!brd) {
51 seq_printf(seq, "no board definition set?\n");
52 return 0;
53 }
54
55 seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh);
56 seq_printf(seq, "auto_io=%u\n", brd->auto_io);
57 seq_printf(seq, "need_io=%u\n", brd->need_io);
58
59 show_max(seq, &brd->max);
60
61
62 return 0;
63}
64
65static int fops_board_open(struct inode *inode, struct file *file)
66{
67 return single_open(file, board_show, NULL);
68}
69
70static const struct file_operations fops_board = {
71 .open = fops_board_open,
72 .read = seq_read,
73 .llseek = seq_lseek,
74 .release = single_release,
75 .owner = THIS_MODULE,
76};
77
78static int info_show(struct seq_file *seq, void *p)
79{
80 struct s3c_cpufreq_config *cfg;
81
82 cfg = s3c_cpufreq_getconfig();
83 if (!cfg) {
84 seq_printf(seq, "no configuration registered\n");
85 return 0;
86 }
87
88 seq_printf(seq, " FCLK %ld Hz\n", cfg->freq.fclk);
89 seq_printf(seq, " HCLK %ld Hz (%lu.%lu ns)\n",
90 cfg->freq.hclk, print_ns(cfg->freq.hclk_tns));
91 seq_printf(seq, " PCLK %ld Hz\n", cfg->freq.hclk);
92 seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk);
93 seq_printf(seq, "\n");
94
95 show_max(seq, &cfg->max);
96
97 seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n",
98 cfg->divs.h_divisor, cfg->divs.p_divisor,
99 cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off");
100 seq_printf(seq, "\n");
101
102 seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll);
103
104 return 0;
105}
106
107static int fops_info_open(struct inode *inode, struct file *file)
108{
109 return single_open(file, info_show, NULL);
110}
111
112static const struct file_operations fops_info = {
113 .open = fops_info_open,
114 .read = seq_read,
115 .llseek = seq_lseek,
116 .release = single_release,
117 .owner = THIS_MODULE,
118};
119
120static int io_show(struct seq_file *seq, void *p)
121{
122 void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *);
123 struct s3c_cpufreq_config *cfg;
124 struct s3c_iotimings *iot;
125 union s3c_iobank *iob;
126 int bank;
127
128 cfg = s3c_cpufreq_getconfig();
129 if (!cfg) {
130 seq_printf(seq, "no configuration registered\n");
131 return 0;
132 }
133
134 show_bank = cfg->info->debug_io_show;
135 if (!show_bank) {
136 seq_printf(seq, "no code to show bank timing\n");
137 return 0;
138 }
139
140 iot = s3c_cpufreq_getiotimings();
141 if (!iot) {
142 seq_printf(seq, "no io timings registered\n");
143 return 0;
144 }
145
146 seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns));
147
148 for (bank = 0; bank < MAX_BANKS; bank++) {
149 iob = &iot->bank[bank];
150
151 seq_printf(seq, "bank %d: ", bank);
152
153 if (!iob->io_2410) {
154 seq_printf(seq, "nothing set\n");
155 continue;
156 }
157
158 show_bank(seq, cfg, iob);
159 }
160
161 return 0;
162}
163
164static int fops_io_open(struct inode *inode, struct file *file)
165{
166 return single_open(file, io_show, NULL);
167}
168
169static const struct file_operations fops_io = {
170 .open = fops_io_open,
171 .read = seq_read,
172 .llseek = seq_lseek,
173 .release = single_release,
174 .owner = THIS_MODULE,
175};
176
177
178static int __init s3c_freq_debugfs_init(void)
179{
180 dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL);
181 if (IS_ERR(dbgfs_root)) {
182 printk(KERN_ERR "%s: error creating debugfs root\n", __func__);
183 return PTR_ERR(dbgfs_root);
184 }
185
186 dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root,
187 NULL, &fops_io);
188
189 dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root,
190 NULL, &fops_info);
191
192 dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root,
193 NULL, &fops_board);
194
195 return 0;
196}
197
198late_initcall(s3c_freq_debugfs_init);
199
diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c
new file mode 100644
index 000000000000..4f1b789a1173
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu-freq.c
@@ -0,0 +1,716 @@
1/* linux/arch/arm/plat-s3c24xx/cpu-freq.c
2 *
3 * Copyright (c) 2006,2007,2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C24XX CPU Frequency scaling
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/cpufreq.h>
19#include <linux/cpu.h>
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <linux/io.h>
23#include <linux/sysdev.h>
24#include <linux/kobject.h>
25#include <linux/sysfs.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29
30#include <plat/cpu.h>
31#include <plat/clock.h>
32#include <plat/cpu-freq-core.h>
33
34#include <mach/regs-clock.h>
35
36/* note, cpufreq support deals in kHz, no Hz */
37
38static struct cpufreq_driver s3c24xx_driver;
39static struct s3c_cpufreq_config cpu_cur;
40static struct s3c_iotimings s3c24xx_iotiming;
41static struct cpufreq_frequency_table *pll_reg;
42static unsigned int last_target = ~0;
43static unsigned int ftab_size;
44static struct cpufreq_frequency_table *ftab;
45
46static struct clk *_clk_mpll;
47static struct clk *_clk_xtal;
48static struct clk *clk_fclk;
49static struct clk *clk_hclk;
50static struct clk *clk_pclk;
51static struct clk *clk_arm;
52
53#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
54struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
55{
56 return &cpu_cur;
57}
58
59struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
60{
61 return &s3c24xx_iotiming;
62}
63#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */
64
65static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
66{
67 unsigned long fclk, pclk, hclk, armclk;
68
69 cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
70 cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
71 cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
72 cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
73
74 cfg->pll.index = __raw_readl(S3C2410_MPLLCON);
75 cfg->pll.frequency = fclk;
76
77 cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
78
79 cfg->divs.h_divisor = fclk / hclk;
80 cfg->divs.p_divisor = fclk / pclk;
81}
82
83static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
84{
85 unsigned long pll = cfg->pll.frequency;
86
87 cfg->freq.fclk = pll;
88 cfg->freq.hclk = pll / cfg->divs.h_divisor;
89 cfg->freq.pclk = pll / cfg->divs.p_divisor;
90
91 /* convert hclk into 10ths of nanoseconds for io calcs */
92 cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
93}
94
95static inline int closer(unsigned int target, unsigned int n, unsigned int c)
96{
97 int diff_cur = abs(target - c);
98 int diff_new = abs(target - n);
99
100 return (diff_new < diff_cur);
101}
102
103static void s3c_cpufreq_show(const char *pfx,
104 struct s3c_cpufreq_config *cfg)
105{
106 s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
107 pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
108 cfg->freq.hclk, cfg->divs.h_divisor,
109 cfg->freq.pclk, cfg->divs.p_divisor);
110}
111
112/* functions to wrapper the driver info calls to do the cpu specific work */
113
114static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
115{
116 if (cfg->info->set_iotiming)
117 (cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
118}
119
120static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
121{
122 if (cfg->info->calc_iotiming)
123 return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
124
125 return 0;
126}
127
128static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
129{
130 (cfg->info->set_refresh)(cfg);
131}
132
133static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
134{
135 (cfg->info->set_divs)(cfg);
136}
137
138static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
139{
140 return (cfg->info->calc_divs)(cfg);
141}
142
143static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
144{
145 (cfg->info->set_fvco)(cfg);
146}
147
148static inline void s3c_cpufreq_resume_clocks(void)
149{
150 cpu_cur.info->resume_clocks();
151}
152
153static inline void s3c_cpufreq_updateclk(struct clk *clk,
154 unsigned int freq)
155{
156 clk_set_rate(clk, freq);
157}
158
159static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
160 unsigned int target_freq,
161 struct cpufreq_frequency_table *pll)
162{
163 struct s3c_cpufreq_freqs freqs;
164 struct s3c_cpufreq_config cpu_new;
165 unsigned long flags;
166
167 cpu_new = cpu_cur; /* copy new from current */
168
169 s3c_cpufreq_show("cur", &cpu_cur);
170
171 /* TODO - check for DMA currently outstanding */
172
173 cpu_new.pll = pll ? *pll : cpu_cur.pll;
174
175 if (pll)
176 freqs.pll_changing = 1;
177
178 /* update our frequencies */
179
180 cpu_new.freq.armclk = target_freq;
181 cpu_new.freq.fclk = cpu_new.pll.frequency;
182
183 if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
184 printk(KERN_ERR "no divisors for %d\n", target_freq);
185 goto err_notpossible;
186 }
187
188 s3c_freq_dbg("%s: got divs\n", __func__);
189
190 s3c_cpufreq_calc(&cpu_new);
191
192 s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
193
194 if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
195 if (s3c_cpufreq_calcio(&cpu_new) < 0) {
196 printk(KERN_ERR "%s: no IO timings\n", __func__);
197 goto err_notpossible;
198 }
199 }
200
201 s3c_cpufreq_show("new", &cpu_new);
202
203 /* setup our cpufreq parameters */
204
205 freqs.old = cpu_cur.freq;
206 freqs.new = cpu_new.freq;
207
208 freqs.freqs.cpu = 0;
209 freqs.freqs.old = cpu_cur.freq.armclk / 1000;
210 freqs.freqs.new = cpu_new.freq.armclk / 1000;
211
212 /* update f/h/p clock settings before we issue the change
213 * notification, so that drivers do not need to do anything
214 * special if they want to recalculate on CPUFREQ_PRECHANGE. */
215
216 s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
217 s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
218 s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
219 s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
220
221 /* start the frequency change */
222
223 if (policy)
224 cpufreq_notify_transition(&freqs.freqs, CPUFREQ_PRECHANGE);
225
226 /* If hclk is staying the same, then we do not need to
227 * re-write the IO or the refresh timings whilst we are changing
228 * speed. */
229
230 local_irq_save(flags);
231
232 /* is our memory clock slowing down? */
233 if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
234 s3c_cpufreq_setrefresh(&cpu_new);
235 s3c_cpufreq_setio(&cpu_new);
236 }
237
238 if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
239 /* not changing PLL, just set the divisors */
240
241 s3c_cpufreq_setdivs(&cpu_new);
242 } else {
243 if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
244 /* slow the cpu down, then set divisors */
245
246 s3c_cpufreq_setfvco(&cpu_new);
247 s3c_cpufreq_setdivs(&cpu_new);
248 } else {
249 /* set the divisors, then speed up */
250
251 s3c_cpufreq_setdivs(&cpu_new);
252 s3c_cpufreq_setfvco(&cpu_new);
253 }
254 }
255
256 /* did our memory clock speed up */
257 if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
258 s3c_cpufreq_setrefresh(&cpu_new);
259 s3c_cpufreq_setio(&cpu_new);
260 }
261
262 /* update our current settings */
263 cpu_cur = cpu_new;
264
265 local_irq_restore(flags);
266
267 /* notify everyone we've done this */
268 if (policy)
269 cpufreq_notify_transition(&freqs.freqs, CPUFREQ_POSTCHANGE);
270
271 s3c_freq_dbg("%s: finished\n", __func__);
272 return 0;
273
274 err_notpossible:
275 printk(KERN_ERR "no compatible settings for %d\n", target_freq);
276 return -EINVAL;
277}
278
279/* s3c_cpufreq_target
280 *
281 * called by the cpufreq core to adjust the frequency that the CPU
282 * is currently running at.
283 */
284
285static int s3c_cpufreq_target(struct cpufreq_policy *policy,
286 unsigned int target_freq,
287 unsigned int relation)
288{
289 struct cpufreq_frequency_table *pll;
290 unsigned int index;
291
292 /* avoid repeated calls which cause a needless amout of duplicated
293 * logging output (and CPU time as the calculation process is
294 * done) */
295 if (target_freq == last_target)
296 return 0;
297
298 last_target = target_freq;
299
300 s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
301 __func__, policy, target_freq, relation);
302
303 if (ftab) {
304 if (cpufreq_frequency_table_target(policy, ftab,
305 target_freq, relation,
306 &index)) {
307 s3c_freq_dbg("%s: table failed\n", __func__);
308 return -EINVAL;
309 }
310
311 s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
312 target_freq, index, ftab[index].frequency);
313 target_freq = ftab[index].frequency;
314 }
315
316 target_freq *= 1000; /* convert target to Hz */
317
318 /* find the settings for our new frequency */
319
320 if (!pll_reg || cpu_cur.lock_pll) {
321 /* either we've not got any PLL values, or we've locked
322 * to the current one. */
323 pll = NULL;
324 } else {
325 struct cpufreq_policy tmp_policy;
326 int ret;
327
328 /* we keep the cpu pll table in Hz, to ensure we get an
329 * accurate value for the PLL output. */
330
331 tmp_policy.min = policy->min * 1000;
332 tmp_policy.max = policy->max * 1000;
333 tmp_policy.cpu = policy->cpu;
334
335 /* cpufreq_frequency_table_target uses a pointer to 'index'
336 * which is the number of the table entry, not the value of
337 * the table entry's index field. */
338
339 ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
340 target_freq, relation,
341 &index);
342
343 if (ret < 0) {
344 printk(KERN_ERR "%s: no PLL available\n", __func__);
345 goto err_notpossible;
346 }
347
348 pll = pll_reg + index;
349
350 s3c_freq_dbg("%s: target %u => %u\n",
351 __func__, target_freq, pll->frequency);
352
353 target_freq = pll->frequency;
354 }
355
356 return s3c_cpufreq_settarget(policy, target_freq, pll);
357
358 err_notpossible:
359 printk(KERN_ERR "no compatible settings for %d\n", target_freq);
360 return -EINVAL;
361}
362
363static unsigned int s3c_cpufreq_get(unsigned int cpu)
364{
365 return clk_get_rate(clk_arm) / 1000;
366}
367
368struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
369{
370 struct clk *clk;
371
372 clk = clk_get(dev, name);
373 if (IS_ERR(clk))
374 printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
375
376 return clk;
377}
378
379static int s3c_cpufreq_init(struct cpufreq_policy *policy)
380{
381 printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
382
383 if (policy->cpu != 0)
384 return -EINVAL;
385
386 policy->cur = s3c_cpufreq_get(0);
387 policy->min = policy->cpuinfo.min_freq = 0;
388 policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
389 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
390
391 /* feed the latency information from the cpu driver */
392 policy->cpuinfo.transition_latency = cpu_cur.info->latency;
393
394 if (ftab)
395 cpufreq_frequency_table_cpuinfo(policy, ftab);
396
397 return 0;
398}
399
400static __init int s3c_cpufreq_initclks(void)
401{
402 _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
403 _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
404 clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
405 clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
406 clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
407 clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
408
409 if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
410 IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
411 printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
412 return -ENOENT;
413 }
414
415 printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
416 clk_get_rate(clk_fclk) / 1000,
417 clk_get_rate(clk_hclk) / 1000,
418 clk_get_rate(clk_pclk) / 1000,
419 clk_get_rate(clk_arm) / 1000);
420
421 return 0;
422}
423
424static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
425{
426 if (policy->cpu != 0)
427 return -EINVAL;
428
429 return 0;
430}
431
432#ifdef CONFIG_PM
433static struct cpufreq_frequency_table suspend_pll;
434static unsigned int suspend_freq;
435
436static int s3c_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
437{
438 suspend_pll.frequency = clk_get_rate(_clk_mpll);
439 suspend_pll.index = __raw_readl(S3C2410_MPLLCON);
440 suspend_freq = s3c_cpufreq_get(0) * 1000;
441
442 return 0;
443}
444
445static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
446{
447 int ret;
448
449 s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
450
451 last_target = ~0; /* invalidate last_target setting */
452
453 /* first, find out what speed we resumed at. */
454 s3c_cpufreq_resume_clocks();
455
456 /* whilst we will be called later on, we try and re-set the
457 * cpu frequencies as soon as possible so that we do not end
458 * up resuming devices and then immediatley having to re-set
459 * a number of settings once these devices have restarted.
460 *
461 * as a note, it is expected devices are not used until they
462 * have been un-suspended and at that time they should have
463 * used the updated clock settings.
464 */
465
466 ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
467 if (ret) {
468 printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
469 return ret;
470 }
471
472 return 0;
473}
474#else
475#define s3c_cpufreq_resume NULL
476#define s3c_cpufreq_suspend NULL
477#endif
478
479static struct cpufreq_driver s3c24xx_driver = {
480 .flags = CPUFREQ_STICKY,
481 .verify = s3c_cpufreq_verify,
482 .target = s3c_cpufreq_target,
483 .get = s3c_cpufreq_get,
484 .init = s3c_cpufreq_init,
485 .suspend = s3c_cpufreq_suspend,
486 .resume = s3c_cpufreq_resume,
487 .name = "s3c24xx",
488};
489
490
491int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
492{
493 if (!info || !info->name) {
494 printk(KERN_ERR "%s: failed to pass valid information\n",
495 __func__);
496 return -EINVAL;
497 }
498
499 printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
500 info->name);
501
502 /* check our driver info has valid data */
503
504 BUG_ON(info->set_refresh == NULL);
505 BUG_ON(info->set_divs == NULL);
506 BUG_ON(info->calc_divs == NULL);
507
508 /* info->set_fvco is optional, depending on whether there
509 * is a need to set the clock code. */
510
511 cpu_cur.info = info;
512
513 /* Note, driver registering should probably update locktime */
514
515 return 0;
516}
517
518int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
519{
520 struct s3c_cpufreq_board *ours;
521
522 if (!board) {
523 printk(KERN_INFO "%s: no board data\n", __func__);
524 return -EINVAL;
525 }
526
527 /* Copy the board information so that each board can make this
528 * initdata. */
529
530 ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
531 if (ours == NULL) {
532 printk(KERN_ERR "%s: no memory\n", __func__);
533 return -ENOMEM;
534 }
535
536 *ours = *board;
537 cpu_cur.board = ours;
538
539 return 0;
540}
541
542int __init s3c_cpufreq_auto_io(void)
543{
544 int ret;
545
546 if (!cpu_cur.info->get_iotiming) {
547 printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
548 return -ENOENT;
549 }
550
551 printk(KERN_INFO "%s: working out IO settings\n", __func__);
552
553 ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
554 if (ret)
555 printk(KERN_ERR "%s: failed to get timings\n", __func__);
556
557 return ret;
558}
559
560/* if one or is zero, then return the other, otherwise return the min */
561#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
562
563/**
564 * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
565 * @dst: The destination structure
566 * @a: One argument.
567 * @b: The other argument.
568 *
569 * Create a minimum of each frequency entry in the 'struct s3c_freq',
570 * unless the entry is zero when it is ignored and the non-zero argument
571 * used.
572 */
573static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
574 struct s3c_freq *a, struct s3c_freq *b)
575{
576 dst->fclk = do_min(a->fclk, b->fclk);
577 dst->hclk = do_min(a->hclk, b->hclk);
578 dst->pclk = do_min(a->pclk, b->pclk);
579 dst->armclk = do_min(a->armclk, b->armclk);
580}
581
582static inline u32 calc_locktime(u32 freq, u32 time_us)
583{
584 u32 result;
585
586 result = freq * time_us;
587 result = DIV_ROUND_UP(result, 1000 * 1000);
588
589 return result;
590}
591
592static void s3c_cpufreq_update_loctkime(void)
593{
594 unsigned int bits = cpu_cur.info->locktime_bits;
595 u32 rate = (u32)clk_get_rate(_clk_xtal);
596 u32 val;
597
598 if (bits == 0) {
599 WARN_ON(1);
600 return;
601 }
602
603 val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
604 val |= calc_locktime(rate, cpu_cur.info->locktime_m);
605
606 printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
607 __raw_writel(val, S3C2410_LOCKTIME);
608}
609
610static int s3c_cpufreq_build_freq(void)
611{
612 int size, ret;
613
614 if (!cpu_cur.info->calc_freqtable)
615 return -EINVAL;
616
617 kfree(ftab);
618 ftab = NULL;
619
620 size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
621 size++;
622
623 ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
624 if (!ftab) {
625 printk(KERN_ERR "%s: no memory for tables\n", __func__);
626 return -ENOMEM;
627 }
628
629 ftab_size = size;
630
631 ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
632 s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
633
634 return 0;
635}
636
637static int __init s3c_cpufreq_initcall(void)
638{
639 int ret = 0;
640
641 if (cpu_cur.info && cpu_cur.board) {
642 ret = s3c_cpufreq_initclks();
643 if (ret)
644 goto out;
645
646 /* get current settings */
647 s3c_cpufreq_getcur(&cpu_cur);
648 s3c_cpufreq_show("cur", &cpu_cur);
649
650 if (cpu_cur.board->auto_io) {
651 ret = s3c_cpufreq_auto_io();
652 if (ret) {
653 printk(KERN_ERR "%s: failed to get io timing\n",
654 __func__);
655 goto out;
656 }
657 }
658
659 if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
660 printk(KERN_ERR "%s: no IO support registered\n",
661 __func__);
662 ret = -EINVAL;
663 goto out;
664 }
665
666 if (!cpu_cur.info->need_pll)
667 cpu_cur.lock_pll = 1;
668
669 s3c_cpufreq_update_loctkime();
670
671 s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
672 &cpu_cur.info->max);
673
674 if (cpu_cur.info->calc_freqtable)
675 s3c_cpufreq_build_freq();
676
677 ret = cpufreq_register_driver(&s3c24xx_driver);
678 }
679
680 out:
681 return ret;
682}
683
684late_initcall(s3c_cpufreq_initcall);
685
686/**
687 * s3c_plltab_register - register CPU PLL table.
688 * @plls: The list of PLL entries.
689 * @plls_no: The size of the PLL entries @plls.
690 *
691 * Register the given set of PLLs with the system.
692 */
693int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
694 unsigned int plls_no)
695{
696 struct cpufreq_frequency_table *vals;
697 unsigned int size;
698
699 size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
700
701 vals = kmalloc(size, GFP_KERNEL);
702 if (vals) {
703 memcpy(vals, plls, size);
704 pll_reg = vals;
705
706 /* write a terminating entry, we don't store it in the
707 * table that is stored in the kernel */
708 vals += plls_no;
709 vals->frequency = CPUFREQ_TABLE_END;
710
711 printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
712 } else
713 printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
714
715 return vals ? 0 : -ENOMEM;
716}
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 1932b7e0da15..5447e60f3936 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -81,7 +81,7 @@ static struct cpu_table cpu_ids[] __initdata = {
81 .map_io = s3c2410_map_io, 81 .map_io = s3c2410_map_io,
82 .init_clocks = s3c2410_init_clocks, 82 .init_clocks = s3c2410_init_clocks,
83 .init_uarts = s3c2410_init_uarts, 83 .init_uarts = s3c2410_init_uarts,
84 .init = s3c2410_init, 84 .init = s3c2410a_init,
85 .name = name_s3c2410a 85 .name = name_s3c2410a
86 }, 86 },
87 { 87 {
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 4eb378c89a39..f52a92ce8dda 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -26,6 +26,8 @@
26#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
27#include <mach/fb.h> 27#include <mach/fb.h>
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/dma.h>
30#include <mach/irqs.h>
29#include <asm/irq.h> 31#include <asm/irq.h>
30 32
31#include <plat/regs-serial.h> 33#include <plat/regs-serial.h>
@@ -180,25 +182,6 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
180 } 182 }
181} 183}
182 184
183/* NAND Controller */
184
185static struct resource s3c_nand_resource[] = {
186 [0] = {
187 .start = S3C24XX_PA_NAND,
188 .end = S3C24XX_PA_NAND + S3C24XX_SZ_NAND - 1,
189 .flags = IORESOURCE_MEM,
190 }
191};
192
193struct platform_device s3c_device_nand = {
194 .name = "s3c2410-nand",
195 .id = -1,
196 .num_resources = ARRAY_SIZE(s3c_nand_resource),
197 .resource = s3c_nand_resource,
198};
199
200EXPORT_SYMBOL(s3c_device_nand);
201
202/* USB Device (Gadget)*/ 185/* USB Device (Gadget)*/
203 186
204static struct resource s3c_usbgadget_resource[] = { 187static struct resource s3c_usbgadget_resource[] = {
@@ -348,7 +331,7 @@ struct platform_device s3c_device_adc = {
348/* HWMON */ 331/* HWMON */
349 332
350struct platform_device s3c_device_hwmon = { 333struct platform_device s3c_device_hwmon = {
351 .name = "s3c24xx-hwmon", 334 .name = "s3c-hwmon",
352 .id = -1, 335 .id = -1,
353 .dev.parent = &s3c_device_adc.dev, 336 .dev.parent = &s3c_device_adc.dev,
354}; 337};
@@ -473,4 +456,52 @@ struct platform_device s3c_device_camif = {
473 456
474EXPORT_SYMBOL(s3c_device_camif); 457EXPORT_SYMBOL(s3c_device_camif);
475 458
459/* AC97 */
460
461static struct resource s3c_ac97_resource[] = {
462 [0] = {
463 .start = S3C2440_PA_AC97,
464 .end = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1,
465 .flags = IORESOURCE_MEM,
466 },
467 [1] = {
468 .start = IRQ_S3C244x_AC97,
469 .end = IRQ_S3C244x_AC97,
470 .flags = IORESOURCE_IRQ,
471 },
472 [2] = {
473 .name = "PCM out",
474 .start = DMACH_PCM_OUT,
475 .end = DMACH_PCM_OUT,
476 .flags = IORESOURCE_DMA,
477 },
478 [3] = {
479 .name = "PCM in",
480 .start = DMACH_PCM_IN,
481 .end = DMACH_PCM_IN,
482 .flags = IORESOURCE_DMA,
483 },
484 [4] = {
485 .name = "Mic in",
486 .start = DMACH_MIC_IN,
487 .end = DMACH_MIC_IN,
488 .flags = IORESOURCE_DMA,
489 },
490};
491
492static u64 s3c_device_ac97_dmamask = 0xffffffffUL;
493
494struct platform_device s3c_device_ac97 = {
495 .name = "s3c-ac97",
496 .id = -1,
497 .num_resources = ARRAY_SIZE(s3c_ac97_resource),
498 .resource = s3c_ac97_resource,
499 .dev = {
500 .dma_mask = &s3c_device_ac97_dmamask,
501 .coherent_dma_mask = 0xffffffffUL
502 }
503};
504
505EXPORT_SYMBOL(s3c_device_ac97);
506
476#endif // CONFIG_CPU_S32440 507#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
new file mode 100644
index 000000000000..efeb025affc7
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
@@ -0,0 +1,282 @@
1/* arch/arm/plat-s3c/include/plat/cpu-freq.h
2 *
3 * Copyright (c) 2006,2007,2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C CPU frequency scaling support - core support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <plat/cpu-freq.h>
15
16struct seq_file;
17
18#define MAX_BANKS (8)
19#define S3C2412_MAX_IO (8)
20
21/**
22 * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
23 * @bankcon: The cached version of settings in this structure.
24 * @tacp:
25 * @tacs: Time from address valid to nCS asserted.
26 * @tcos: Time from nCS asserted to nOE or nWE asserted.
27 * @tacc: Time that nOE or nWE is asserted.
28 * @tcoh: Time nCS is held after nOE or nWE are released.
29 * @tcah: Time address is held for after
30 * @nwait_en: Whether nWAIT is enabled for this bank.
31 *
32 * This structure represents the IO timings for a S3C2410 style IO bank
33 * used by the CPU frequency support if it needs to change the settings
34 * of the IO.
35 */
36struct s3c2410_iobank_timing {
37 unsigned long bankcon;
38 unsigned int tacp;
39 unsigned int tacs;
40 unsigned int tcos;
41 unsigned int tacc;
42 unsigned int tcoh; /* nCS hold afrer nOE/nWE */
43 unsigned int tcah; /* Address hold after nCS */
44 unsigned char nwait_en; /* nWait enabled for bank. */
45};
46
47/**
48 * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO
49 * @idcy: The idle cycle time between transactions.
50 * @wstrd: nCS release to end of read cycle.
51 * @wstwr: nCS release to end of write cycle.
52 * @wstoen: nCS assertion to nOE assertion time.
53 * @wstwen: nCS assertion to nWE assertion time.
54 * @wstbrd: Burst ready delay.
55 * @smbidcyr: Register cache for smbidcyr value.
56 * @smbwstrd: Register cache for smbwstrd value.
57 * @smbwstwr: Register cache for smbwstwr value.
58 * @smbwstoen: Register cache for smbwstoen value.
59 * @smbwstwen: Register cache for smbwstwen value.
60 * @smbwstbrd: Register cache for smbwstbrd value.
61 *
62 * Timing information for a IO bank on an S3C2412 or similar system which
63 * uses a PL093 block.
64 */
65struct s3c2412_iobank_timing {
66 unsigned int idcy;
67 unsigned int wstrd;
68 unsigned int wstwr;
69 unsigned int wstoen;
70 unsigned int wstwen;
71 unsigned int wstbrd;
72
73 /* register cache */
74 unsigned char smbidcyr;
75 unsigned char smbwstrd;
76 unsigned char smbwstwr;
77 unsigned char smbwstoen;
78 unsigned char smbwstwen;
79 unsigned char smbwstbrd;
80};
81
82union s3c_iobank {
83 struct s3c2410_iobank_timing *io_2410;
84 struct s3c2412_iobank_timing *io_2412;
85};
86
87/**
88 * struct s3c_iotimings - Chip IO timings holder
89 * @bank: The timings for each IO bank.
90 */
91struct s3c_iotimings {
92 union s3c_iobank bank[MAX_BANKS];
93};
94
95/**
96 * struct s3c_plltab - PLL table information.
97 * @vals: List of PLL values.
98 * @size: Size of the PLL table @vals.
99 */
100struct s3c_plltab {
101 struct s3c_pllval *vals;
102 int size;
103};
104
105/**
106 * struct s3c_cpufreq_config - current cpu frequency configuration
107 * @freq: The current settings for the core clocks.
108 * @max: Maxium settings, derived from core, board and user settings.
109 * @pll: The PLL table entry for the current PLL settings.
110 * @divs: The divisor settings for the core clocks.
111 * @info: The current core driver information.
112 * @board: The information for the board we are running on.
113 * @lock_pll: Set if the PLL settings cannot be changed.
114 *
115 * This is for the core drivers that need to know information about
116 * the current settings and values. It should not be needed by any
117 * device drivers.
118*/
119struct s3c_cpufreq_config {
120 struct s3c_freq freq;
121 struct s3c_freq max;
122 struct cpufreq_frequency_table pll;
123 struct s3c_clkdivs divs;
124 struct s3c_cpufreq_info *info; /* for core, not drivers */
125 struct s3c_cpufreq_board *board;
126
127 unsigned int lock_pll:1;
128};
129
130/**
131 * struct s3c_cpufreq_info - Information for the CPU frequency driver.
132 * @name: The name of this implementation.
133 * @max: The maximum frequencies for the system.
134 * @latency: Transition latency to give to cpufreq.
135 * @locktime_m: The lock-time in uS for the MPLL.
136 * @locktime_u: The lock-time in uS for the UPLL.
137 * @locttime_bits: The number of bits each LOCKTIME field.
138 * @need_pll: Set if this driver needs to change the PLL values to acheive
139 * any frequency changes. This is really only need by devices like the
140 * S3C2410 where there is no or limited divider between the PLL and the
141 * ARMCLK.
142 * @resume_clocks: Update the clocks on resume.
143 * @get_iotiming: Get the current IO timing data, mainly for use at start.
144 * @set_iotiming: Update the IO timings from the cached copies calculated
145 * from the @calc_iotiming entry when changing the frequency.
146 * @calc_iotiming: Calculate and update the cached copies of the IO timings
147 * from the newly calculated frequencies.
148 * @calc_freqtable: Calculate (fill in) the given frequency table from the
149 * current frequency configuration. If the table passed in is NULL,
150 * then the return is the number of elements to be filled for allocation
151 * of the table.
152 * @set_refresh: Set the memory refresh configuration.
153 * @set_fvco: Set the PLL frequencies.
154 * @set_divs: Update the clock divisors.
155 * @calc_divs: Calculate the clock divisors.
156 */
157struct s3c_cpufreq_info {
158 const char *name;
159 struct s3c_freq max;
160
161 unsigned int latency;
162
163 unsigned int locktime_m;
164 unsigned int locktime_u;
165 unsigned char locktime_bits;
166
167 unsigned int need_pll:1;
168
169 /* driver routines */
170
171 void (*resume_clocks)(void);
172
173 int (*get_iotiming)(struct s3c_cpufreq_config *cfg,
174 struct s3c_iotimings *timings);
175
176 void (*set_iotiming)(struct s3c_cpufreq_config *cfg,
177 struct s3c_iotimings *timings);
178
179 int (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
180 struct s3c_iotimings *timings);
181
182 int (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
183 struct cpufreq_frequency_table *t,
184 size_t table_size);
185
186 void (*debug_io_show)(struct seq_file *seq,
187 struct s3c_cpufreq_config *cfg,
188 union s3c_iobank *iob);
189
190 void (*set_refresh)(struct s3c_cpufreq_config *cfg);
191 void (*set_fvco)(struct s3c_cpufreq_config *cfg);
192 void (*set_divs)(struct s3c_cpufreq_config *cfg);
193 int (*calc_divs)(struct s3c_cpufreq_config *cfg);
194};
195
196extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
197
198extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no);
199
200/* exports and utilities for debugfs */
201extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
202extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
203
204extern void s3c2410_iotiming_debugfs(struct seq_file *seq,
205 struct s3c_cpufreq_config *cfg,
206 union s3c_iobank *iob);
207
208extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
209 struct s3c_cpufreq_config *cfg,
210 union s3c_iobank *iob);
211
212#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
213#define s3c_cpufreq_debugfs_call(x) x
214#else
215#define s3c_cpufreq_debugfs_call(x) NULL
216#endif
217
218/* Useful utility functions. */
219
220extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
221
222/* S3C2410 and compatible exported functions */
223
224extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
225
226extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
227 struct s3c_iotimings *iot);
228
229extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
230 struct s3c_iotimings *timings);
231
232extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
233 struct s3c_iotimings *iot);
234
235extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
236
237/* S3C2412 compatible routines */
238
239extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
240 struct s3c_iotimings *timings);
241
242extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
243 struct s3c_iotimings *timings);
244
245extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
246 struct s3c_iotimings *iot);
247
248extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
249 struct s3c_iotimings *iot);
250
251#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
252#define s3c_freq_dbg(x...) printk(KERN_INFO x)
253#else
254#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
255#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
256
257#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
258#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
259#else
260#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
261#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
262
263static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
264 int index, size_t table_size,
265 unsigned int freq)
266{
267 if (index < 0)
268 return index;
269
270 if (table) {
271 if (index >= table_size)
272 return -ENOMEM;
273
274 s3c_freq_dbg("%s: { %d = %u kHz }\n",
275 __func__, index, freq);
276
277 table[index].index = index;
278 table[index].frequency = freq;
279 }
280
281 return index + 1;
282}
diff --git a/arch/arm/plat-s3c24xx/include/plat/fiq.h b/arch/arm/plat-s3c24xx/include/plat/fiq.h
new file mode 100644
index 000000000000..8521b8372c5f
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/fiq.h
@@ -0,0 +1,13 @@
1/* linux/include/asm-arm/plat-s3c24xx/fiq.h
2 *
3 * Copyright (c) 2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Header file for S3C24XX CPU FIQ support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13extern int s3c24xx_set_fiq(unsigned int irq, bool on);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
index a9ac9e29759e..b6deeef8f663 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
@@ -14,6 +14,7 @@
14#ifdef CONFIG_CPU_S3C2410 14#ifdef CONFIG_CPU_S3C2410
15 15
16extern int s3c2410_init(void); 16extern int s3c2410_init(void);
17extern int s3c2410a_init(void);
17 18
18extern void s3c2410_map_io(void); 19extern void s3c2410_map_io(void);
19 20
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 958737775ad2..d02f5f02045e 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -493,6 +493,38 @@ s3c_irq_demux_extint4t7(unsigned int irq,
493 } 493 }
494} 494}
495 495
496#ifdef CONFIG_FIQ
497/**
498 * s3c24xx_set_fiq - set the FIQ routing
499 * @irq: IRQ number to route to FIQ on processor.
500 * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
501 *
502 * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
503 * @on is true, the @irq is checked to see if it can be routed and the
504 * interrupt controller updated to route the IRQ. If @on is false, the FIQ
505 * routing is cleared, regardless of which @irq is specified.
506 */
507int s3c24xx_set_fiq(unsigned int irq, bool on)
508{
509 u32 intmod;
510 unsigned offs;
511
512 if (on) {
513 offs = irq - FIQ_START;
514 if (offs > 31)
515 return -EINVAL;
516
517 intmod = 1 << offs;
518 } else {
519 intmod = 0;
520 }
521
522 __raw_writel(intmod, S3C2410_INTMOD);
523 return 0;
524}
525#endif
526
527
496/* s3c24xx_init_irq 528/* s3c24xx_init_irq
497 * 529 *
498 * Initialise S3C2410 IRQ system 530 * Initialise S3C2410 IRQ system
@@ -505,6 +537,10 @@ void __init s3c24xx_init_irq(void)
505 int irqno; 537 int irqno;
506 int i; 538 int i;
507 539
540#ifdef CONFIG_FIQ
541 init_FIQ();
542#endif
543
508 irqdbf("s3c2410_init_irq: clearing interrupt status flags\n"); 544 irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
509 545
510 /* first, clear all interrupts pending... */ 546 /* first, clear all interrupts pending... */
diff --git a/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
new file mode 100644
index 000000000000..43ea80190d87
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
@@ -0,0 +1,64 @@
1/* linux/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
2 *
3 * Copyright (c) 2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/cpufreq.h>
17#include <linux/io.h>
18
19#include <mach/map.h>
20#include <mach/regs-mem.h>
21#include <mach/regs-clock.h>
22
23#include <plat/cpu-freq-core.h>
24
25/**
26 * s3c2410_cpufreq_setrefresh - set SDRAM refresh value
27 * @cfg: The frequency configuration
28 *
29 * Set the SDRAM refresh value appropriately for the configured
30 * frequency.
31 */
32void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
33{
34 struct s3c_cpufreq_board *board = cfg->board;
35 unsigned long refresh;
36 unsigned long refval;
37
38 /* Reduce both the refresh time (in ns) and the frequency (in MHz)
39 * down to ensure that we do not overflow 32 bit numbers.
40 *
41 * This should work for HCLK up to 133MHz and refresh period up
42 * to 30usec.
43 */
44
45 refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
46 refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */
47 refresh = (1 << 11) + 1 - refresh;
48
49 s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh);
50
51 refval = __raw_readl(S3C2410_REFRESH);
52 refval &= ~((1 << 12) - 1);
53 refval |= refresh;
54 __raw_writel(refval, S3C2410_REFRESH);
55}
56
57/**
58 * s3c2410_set_fvco - set the PLL value
59 * @cfg: The frequency configuration
60 */
61void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
62{
63 __raw_writel(cfg->pll.index, S3C2410_MPLLCON);
64}
diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
new file mode 100644
index 000000000000..d0a3a145cd4d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
@@ -0,0 +1,477 @@
1/* linux/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
2 *
3 * Copyright (c) 2006,2008,2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/cpufreq.h>
18#include <linux/seq_file.h>
19#include <linux/io.h>
20
21#include <mach/map.h>
22#include <mach/regs-mem.h>
23#include <mach/regs-clock.h>
24
25#include <plat/cpu-freq-core.h>
26
27#define print_ns(x) ((x) / 10), ((x) % 10)
28
29/**
30 * s3c2410_print_timing - print bank timing data for debug purposes
31 * @pfx: The prefix to put on the output
32 * @timings: The timing inforamtion to print.
33*/
34static void s3c2410_print_timing(const char *pfx,
35 struct s3c_iotimings *timings)
36{
37 struct s3c2410_iobank_timing *bt;
38 int bank;
39
40 for (bank = 0; bank < MAX_BANKS; bank++) {
41 bt = timings->bank[bank].io_2410;
42 if (!bt)
43 continue;
44
45 printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, "
46 "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank,
47 print_ns(bt->tacs),
48 print_ns(bt->tcos),
49 print_ns(bt->tacc),
50 print_ns(bt->tcoh),
51 print_ns(bt->tcah));
52 }
53}
54
55/**
56 * bank_reg - convert bank number to pointer to the control register.
57 * @bank: The IO bank number.
58 */
59static inline void __iomem *bank_reg(unsigned int bank)
60{
61 return S3C2410_BANKCON0 + (bank << 2);
62}
63
64/**
65 * bank_is_io - test whether bank is used for IO
66 * @bankcon: The bank control register.
67 *
68 * This is a simplistic test to see if any BANKCON[x] is not an IO
69 * bank. It currently does not take into account whether BWSCON has
70 * an illegal width-setting in it, or if the pin connected to nCS[x]
71 * is actually being handled as a chip-select.
72 */
73static inline int bank_is_io(unsigned long bankcon)
74{
75 return !(bankcon & S3C2410_BANKCON_SDRAM);
76}
77
78/**
79 * to_div - convert cycle time to divisor
80 * @cyc: The cycle time, in 10ths of nanoseconds.
81 * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
82 *
83 * Convert the given cycle time into the divisor to use to obtain it from
84 * HCLK.
85*/
86static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns)
87{
88 if (cyc == 0)
89 return 0;
90
91 return DIV_ROUND_UP(cyc, hclk_tns);
92}
93
94/**
95 * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4
96 * @cyc: The cycle time, in 10ths of nanoseconds.
97 * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
98 * @v: Pointer to register to alter.
99 * @shift: The shift to get to the control bits.
100 *
101 * Calculate the divisor, and turn it into the correct control bits to
102 * set in the result, @v.
103 */
104static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns,
105 unsigned long *v, int shift)
106{
107 unsigned int div = to_div(cyc, hclk_tns);
108 unsigned long val;
109
110 s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n",
111 __func__, cyc, hclk_tns, shift, div);
112
113 switch (div) {
114 case 0:
115 val = 0;
116 break;
117 case 1:
118 val = 1;
119 break;
120 case 2:
121 val = 2;
122 break;
123 case 3:
124 case 4:
125 val = 3;
126 break;
127 default:
128 return -1;
129 }
130
131 *v |= val << shift;
132 return 0;
133}
134
135int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v)
136{
137 /* Currently no support for Tacp calculations. */
138 return 0;
139}
140
141/**
142 * calc_tacc - calculate divisor control for tacc.
143 * @cyc: The cycle time, in 10ths of nanoseconds.
144 * @nwait_en: IS nWAIT enabled for this bank.
145 * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
146 * @v: Pointer to register to alter.
147 *
148 * Calculate the divisor control for tACC, taking into account whether
149 * the bank has nWAIT enabled. The result is used to modify the value
150 * pointed to by @v.
151*/
152static int calc_tacc(unsigned int cyc, int nwait_en,
153 unsigned long hclk_tns, unsigned long *v)
154{
155 unsigned int div = to_div(cyc, hclk_tns);
156 unsigned long val;
157
158 s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n",
159 __func__, cyc, nwait_en, hclk_tns, div);
160
161 /* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */
162 if (nwait_en && div < 4)
163 div = 4;
164
165 switch (div) {
166 case 0:
167 val = 0;
168 break;
169
170 case 1:
171 case 2:
172 case 3:
173 case 4:
174 val = div - 1;
175 break;
176
177 case 5:
178 case 6:
179 val = 4;
180 break;
181
182 case 7:
183 case 8:
184 val = 5;
185 break;
186
187 case 9:
188 case 10:
189 val = 6;
190 break;
191
192 case 11:
193 case 12:
194 case 13:
195 case 14:
196 val = 7;
197 break;
198
199 default:
200 return -1;
201 }
202
203 *v |= val << 8;
204 return 0;
205}
206
207/**
208 * s3c2410_calc_bank - calculate bank timing infromation
209 * @cfg: The configuration we need to calculate for.
210 * @bt: The bank timing information.
211 *
212 * Given the cycle timine for a bank @bt, calculate the new BANKCON
213 * setting for the @cfg timing. This updates the timing information
214 * ready for the cpu frequency change.
215 */
216static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg,
217 struct s3c2410_iobank_timing *bt)
218{
219 unsigned long hclk = cfg->freq.hclk_tns;
220 unsigned long res;
221 int ret;
222
223 res = bt->bankcon;
224 res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16);
225
226 /* tacp: 2,3,4,5 */
227 /* tcah: 0,1,2,4 */
228 /* tcoh: 0,1,2,4 */
229 /* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */
230 /* tcos: 0,1,2,4 */
231 /* tacs: 0,1,2,4 */
232
233 ret = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT);
234 ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT);
235 ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT);
236 ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT);
237
238 if (ret)
239 return -EINVAL;
240
241 ret |= calc_tacp(bt->tacp, hclk, &res);
242 ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res);
243
244 if (ret)
245 return -EINVAL;
246
247 bt->bankcon = res;
248 return 0;
249}
250
251static unsigned int tacc_tab[] = {
252 [0] = 1,
253 [1] = 2,
254 [2] = 3,
255 [3] = 4,
256 [4] = 6,
257 [5] = 9,
258 [6] = 10,
259 [7] = 14,
260};
261
262/**
263 * get_tacc - turn tACC value into cycle time
264 * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
265 * @val: The bank timing register value, shifed down.
266 */
267static unsigned int get_tacc(unsigned long hclk_tns,
268 unsigned long val)
269{
270 val &= 7;
271 return hclk_tns * tacc_tab[val];
272}
273
274/**
275 * get_0124 - turn 0/1/2/4 divider into cycle time
276 * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
277 * @val: The bank timing register value, shifed down.
278 */
279static unsigned int get_0124(unsigned long hclk_tns,
280 unsigned long val)
281{
282 val &= 3;
283 return hclk_tns * ((val == 3) ? 4 : val);
284}
285
286/**
287 * s3c2410_iotiming_getbank - turn BANKCON into cycle time information
288 * @cfg: The frequency configuration
289 * @bt: The bank timing to fill in (uses cached BANKCON)
290 *
291 * Given the BANKCON setting in @bt and the current frequency settings
292 * in @cfg, update the cycle timing information.
293 */
294void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg,
295 struct s3c2410_iobank_timing *bt)
296{
297 unsigned long bankcon = bt->bankcon;
298 unsigned long hclk = cfg->freq.hclk_tns;
299
300 bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
301 bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
302 bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
303 bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
304 bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
305}
306
307/**
308 * s3c2410_iotiming_debugfs - debugfs show io bank timing information
309 * @seq: The seq_file to write output to using seq_printf().
310 * @cfg: The current configuration.
311 * @iob: The IO bank information to decode.
312 */
313void s3c2410_iotiming_debugfs(struct seq_file *seq,
314 struct s3c_cpufreq_config *cfg,
315 union s3c_iobank *iob)
316{
317 struct s3c2410_iobank_timing *bt = iob->io_2410;
318 unsigned long bankcon = bt->bankcon;
319 unsigned long hclk = cfg->freq.hclk_tns;
320 unsigned int tacs;
321 unsigned int tcos;
322 unsigned int tacc;
323 unsigned int tcoh;
324 unsigned int tcah;
325
326 seq_printf(seq, "BANKCON=0x%08lx\n", bankcon);
327
328 tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
329 tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
330 tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
331 tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
332 tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
333
334 seq_printf(seq,
335 "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
336 print_ns(bt->tacs),
337 print_ns(bt->tcos),
338 print_ns(bt->tacc),
339 print_ns(bt->tcoh),
340 print_ns(bt->tcah));
341
342 seq_printf(seq,
343 "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
344 print_ns(tacs),
345 print_ns(tcos),
346 print_ns(tacc),
347 print_ns(tcoh),
348 print_ns(tcah));
349}
350
351/**
352 * s3c2410_iotiming_calc - Calculate bank timing for frequency change.
353 * @cfg: The frequency configuration
354 * @iot: The IO timing information to fill out.
355 *
356 * Calculate the new values for the banks in @iot based on the new
357 * frequency information in @cfg. This is then used by s3c2410_iotiming_set()
358 * to update the timing when necessary.
359 */
360int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
361 struct s3c_iotimings *iot)
362{
363 struct s3c2410_iobank_timing *bt;
364 unsigned long bankcon;
365 int bank;
366 int ret;
367
368 for (bank = 0; bank < MAX_BANKS; bank++) {
369 bankcon = __raw_readl(bank_reg(bank));
370 bt = iot->bank[bank].io_2410;
371
372 if (!bt)
373 continue;
374
375 bt->bankcon = bankcon;
376
377 ret = s3c2410_calc_bank(cfg, bt);
378 if (ret) {
379 printk(KERN_ERR "%s: cannot calculate bank %d io\n",
380 __func__, bank);
381 goto err;
382 }
383
384 s3c_freq_iodbg("%s: bank %d: con=%08lx\n",
385 __func__, bank, bt->bankcon);
386 }
387
388 return 0;
389 err:
390 return ret;
391}
392
393/**
394 * s3c2410_iotiming_set - set the IO timings from the given setup.
395 * @cfg: The frequency configuration
396 * @iot: The IO timing information to use.
397 *
398 * Set all the currently used IO bank timing information generated
399 * by s3c2410_iotiming_calc() once the core has validated that all
400 * the new values are within permitted bounds.
401 */
402void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
403 struct s3c_iotimings *iot)
404{
405 struct s3c2410_iobank_timing *bt;
406 int bank;
407
408 /* set the io timings from the specifier */
409
410 for (bank = 0; bank < MAX_BANKS; bank++) {
411 bt = iot->bank[bank].io_2410;
412 if (!bt)
413 continue;
414
415 __raw_writel(bt->bankcon, bank_reg(bank));
416 }
417}
418
419/**
420 * s3c2410_iotiming_get - Get the timing information from current registers.
421 * @cfg: The frequency configuration
422 * @timings: The IO timing information to fill out.
423 *
424 * Calculate the @timings timing information from the current frequency
425 * information in @cfg, and the new frequency configur
426 * through all the IO banks, reading the state and then updating @iot
427 * as necessary.
428 *
429 * This is used at the moment on initialisation to get the current
430 * configuration so that boards do not have to carry their own setup
431 * if the timings are correct on initialisation.
432 */
433
434int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
435 struct s3c_iotimings *timings)
436{
437 struct s3c2410_iobank_timing *bt;
438 unsigned long bankcon;
439 unsigned long bwscon;
440 int bank;
441
442 bwscon = __raw_readl(S3C2410_BWSCON);
443
444 /* look through all banks to see what is currently set. */
445
446 for (bank = 0; bank < MAX_BANKS; bank++) {
447 bankcon = __raw_readl(bank_reg(bank));
448
449 if (!bank_is_io(bankcon))
450 continue;
451
452 s3c_freq_iodbg("%s: bank %d: con %08lx\n",
453 __func__, bank, bankcon);
454
455 bt = kzalloc(sizeof(struct s3c2410_iobank_timing), GFP_KERNEL);
456 if (!bt) {
457 printk(KERN_ERR "%s: no memory for bank\n", __func__);
458 return -ENOMEM;
459 }
460
461 /* find out in nWait is enabled for bank. */
462
463 if (bank != 0) {
464 unsigned long tmp = S3C2410_BWSCON_GET(bwscon, bank);
465 if (tmp & S3C2410_BWSCON_WS)
466 bt->nwait_en = 1;
467 }
468
469 timings->bank[bank].io_2410 = bt;
470 bt->bankcon = bankcon;
471
472 s3c2410_iotiming_getbank(cfg, bt);
473 }
474
475 s3c2410_print_timing("get", timings);
476 return 0;
477}
diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
new file mode 100644
index 000000000000..fd45e47facbc
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
@@ -0,0 +1,285 @@
1/* linux/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
2 *
3 * Copyright (c) 2006,2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C2412/S3C2443 (PL093 based) IO timing support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/cpufreq.h>
19#include <linux/seq_file.h>
20#include <linux/sysdev.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24
25#include <linux/amba/pl093.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29
30#include <mach/regs-s3c2412-mem.h>
31
32#include <plat/cpu.h>
33#include <plat/cpu-freq-core.h>
34#include <plat/clock.h>
35
36#define print_ns(x) ((x) / 10), ((x) % 10)
37
38/**
39 * s3c2412_print_timing - print timing infromation via printk.
40 * @pfx: The prefix to print each line with.
41 * @iot: The IO timing information
42 */
43static void s3c2412_print_timing(const char *pfx, struct s3c_iotimings *iot)
44{
45 struct s3c2412_iobank_timing *bt;
46 unsigned int bank;
47
48 for (bank = 0; bank < MAX_BANKS; bank++) {
49 bt = iot->bank[bank].io_2412;
50 if (!bt)
51 continue;
52
53 printk(KERN_DEBUG "%s: %d: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
54 "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", pfx, bank,
55 print_ns(bt->idcy),
56 print_ns(bt->wstrd),
57 print_ns(bt->wstwr),
58 print_ns(bt->wstoen),
59 print_ns(bt->wstwen),
60 print_ns(bt->wstbrd));
61 }
62}
63
64/**
65 * to_div - turn a cycle length into a divisor setting.
66 * @cyc_tns: The cycle time in 10ths of nanoseconds.
67 * @clk_tns: The clock period in 10ths of nanoseconds.
68 */
69static inline unsigned int to_div(unsigned int cyc_tns, unsigned int clk_tns)
70{
71 return cyc_tns ? DIV_ROUND_UP(cyc_tns, clk_tns) : 0;
72}
73
74/**
75 * calc_timing - calculate timing divisor value and check in range.
76 * @hwtm: The hardware timing in 10ths of nanoseconds.
77 * @clk_tns: The clock period in 10ths of nanoseconds.
78 * @err: Pointer to err variable to update in event of failure.
79 */
80static unsigned int calc_timing(unsigned int hwtm, unsigned int clk_tns,
81 unsigned int *err)
82{
83 unsigned int ret = to_div(hwtm, clk_tns);
84
85 if (ret > 0xf)
86 *err = -EINVAL;
87
88 return ret;
89}
90
91/**
92 * s3c2412_calc_bank - calculate the bank divisor settings.
93 * @cfg: The current frequency configuration.
94 * @bt: The bank timing.
95 */
96static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg,
97 struct s3c2412_iobank_timing *bt)
98{
99 unsigned int hclk = cfg->freq.hclk_tns;
100 int err = 0;
101
102 bt->smbidcyr = calc_timing(bt->idcy, hclk, &err);
103 bt->smbwstrd = calc_timing(bt->wstrd, hclk, &err);
104 bt->smbwstwr = calc_timing(bt->wstwr, hclk, &err);
105 bt->smbwstoen = calc_timing(bt->wstoen, hclk, &err);
106 bt->smbwstwen = calc_timing(bt->wstwen, hclk, &err);
107 bt->smbwstbrd = calc_timing(bt->wstbrd, hclk, &err);
108
109 return err;
110}
111
112/**
113 * s3c2412_iotiming_debugfs - debugfs show io bank timing information
114 * @seq: The seq_file to write output to using seq_printf().
115 * @cfg: The current configuration.
116 * @iob: The IO bank information to decode.
117*/
118void s3c2412_iotiming_debugfs(struct seq_file *seq,
119 struct s3c_cpufreq_config *cfg,
120 union s3c_iobank *iob)
121{
122 struct s3c2412_iobank_timing *bt = iob->io_2412;
123
124 seq_printf(seq,
125 "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
126 "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n",
127 print_ns(bt->idcy),
128 print_ns(bt->wstrd),
129 print_ns(bt->wstwr),
130 print_ns(bt->wstoen),
131 print_ns(bt->wstwen),
132 print_ns(bt->wstbrd));
133}
134
135/**
136 * s3c2412_iotiming_calc - calculate all the bank divisor settings.
137 * @cfg: The current frequency configuration.
138 * @iot: The bank timing information.
139 *
140 * Calculate the timing information for all the banks that are
141 * configured as IO, using s3c2412_calc_bank().
142 */
143int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
144 struct s3c_iotimings *iot)
145{
146 struct s3c2412_iobank_timing *bt;
147 int bank;
148 int ret;
149
150 for (bank = 0; bank < MAX_BANKS; bank++) {
151 bt = iot->bank[bank].io_2412;
152 if (!bt)
153 continue;
154
155 ret = s3c2412_calc_bank(cfg, bt);
156 if (ret) {
157 printk(KERN_ERR "%s: cannot calculate bank %d io\n",
158 __func__, bank);
159 goto err;
160 }
161 }
162
163 return 0;
164 err:
165 return ret;
166}
167
168/**
169 * s3c2412_iotiming_set - set the timing information
170 * @cfg: The current frequency configuration.
171 * @iot: The bank timing information.
172 *
173 * Set the IO bank information from the details calculated earlier from
174 * calling s3c2412_iotiming_calc().
175 */
176void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
177 struct s3c_iotimings *iot)
178{
179 struct s3c2412_iobank_timing *bt;
180 void __iomem *regs;
181 int bank;
182
183 /* set the io timings from the specifier */
184
185 for (bank = 0; bank < MAX_BANKS; bank++) {
186 bt = iot->bank[bank].io_2412;
187 if (!bt)
188 continue;
189
190 regs = S3C2412_SSMC_BANK(bank);
191
192 __raw_writel(bt->smbidcyr, regs + SMBIDCYR);
193 __raw_writel(bt->smbwstrd, regs + SMBWSTRDR);
194 __raw_writel(bt->smbwstwr, regs + SMBWSTWRR);
195 __raw_writel(bt->smbwstoen, regs + SMBWSTOENR);
196 __raw_writel(bt->smbwstwen, regs + SMBWSTWENR);
197 __raw_writel(bt->smbwstbrd, regs + SMBWSTBRDR);
198 }
199}
200
201static inline unsigned int s3c2412_decode_timing(unsigned int clock, u32 reg)
202{
203 return (reg & 0xf) * clock;
204}
205
206static void s3c2412_iotiming_getbank(struct s3c_cpufreq_config *cfg,
207 struct s3c2412_iobank_timing *bt,
208 unsigned int bank)
209{
210 unsigned long clk = cfg->freq.hclk_tns; /* ssmc clock??? */
211 void __iomem *regs = S3C2412_SSMC_BANK(bank);
212
213 bt->idcy = s3c2412_decode_timing(clk, __raw_readl(regs + SMBIDCYR));
214 bt->wstrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTRDR));
215 bt->wstoen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTOENR));
216 bt->wstwen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTWENR));
217 bt->wstbrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTBRDR));
218}
219
220/**
221 * bank_is_io - return true if bank is (possibly) IO.
222 * @bank: The bank number.
223 * @bankcfg: The value of S3C2412_EBI_BANKCFG.
224 */
225static inline bool bank_is_io(unsigned int bank, u32 bankcfg)
226{
227 if (bank < 2)
228 return true;
229
230 return !(bankcfg & (1 << bank));
231}
232
233int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
234 struct s3c_iotimings *timings)
235{
236 struct s3c2412_iobank_timing *bt;
237 u32 bankcfg = __raw_readl(S3C2412_EBI_BANKCFG);
238 unsigned int bank;
239
240 /* look through all banks to see what is currently set. */
241
242 for (bank = 0; bank < MAX_BANKS; bank++) {
243 if (!bank_is_io(bank, bankcfg))
244 continue;
245
246 bt = kzalloc(sizeof(struct s3c2412_iobank_timing), GFP_KERNEL);
247 if (!bt) {
248 printk(KERN_ERR "%s: no memory for bank\n", __func__);
249 return -ENOMEM;
250 }
251
252 timings->bank[bank].io_2412 = bt;
253 s3c2412_iotiming_getbank(cfg, bt, bank);
254 }
255
256 s3c2412_print_timing("get", timings);
257 return 0;
258}
259
260/* this is in here as it is so small, it doesn't currently warrant a file
261 * to itself. We expect that any s3c24xx needing this is going to also
262 * need the iotiming support.
263 */
264void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
265{
266 struct s3c_cpufreq_board *board = cfg->board;
267 u32 refresh;
268
269 WARN_ON(board == NULL);
270
271 /* Reduce both the refresh time (in ns) and the frequency (in MHz)
272 * down to ensure that we do not overflow 32 bit numbers.
273 *
274 * This should work for HCLK up to 133MHz and refresh period up
275 * to 30usec.
276 */
277
278 refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
279 refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */
280 refresh &= ((1 << 16) - 1);
281
282 s3c_freq_dbg("%s: refresh value %u\n", __func__, (unsigned int)refresh);
283
284 __raw_writel(refresh, S3C2412_REFRESH);
285}
diff --git a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
new file mode 100644
index 000000000000..ae2e6c604f27
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
@@ -0,0 +1,311 @@
1/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
2 *
3 * Copyright (c) 2006,2008,2009 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 * Vincent Sanders <vince@simtec.co.uk>
7 *
8 * S3C2440/S3C2442 CPU Frequency scaling
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/cpufreq.h>
20#include <linux/sysdev.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/io.h>
25
26#include <mach/hardware.h>
27
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30
31#include <mach/regs-clock.h>
32
33#include <plat/cpu.h>
34#include <plat/cpu-freq-core.h>
35#include <plat/clock.h>
36
37static struct clk *xtal;
38static struct clk *fclk;
39static struct clk *hclk;
40static struct clk *armclk;
41
42/* HDIV: 1, 2, 3, 4, 6, 8 */
43
44static inline int within_khz(unsigned long a, unsigned long b)
45{
46 long diff = a - b;
47
48 return (diff >= -1000 && diff <= 1000);
49}
50
51/**
52 * s3c2440_cpufreq_calcdivs - calculate divider settings
53 * @cfg: The cpu frequency settings.
54 *
55 * Calcualte the divider values for the given frequency settings
56 * specified in @cfg. The values are stored in @cfg for later use
57 * by the relevant set routine if the request settings can be reached.
58 */
59int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
60{
61 unsigned int hdiv, pdiv;
62 unsigned long hclk, fclk, armclk;
63 unsigned long hclk_max;
64
65 fclk = cfg->freq.fclk;
66 armclk = cfg->freq.armclk;
67 hclk_max = cfg->max.hclk;
68
69 s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
70 __func__, fclk, armclk, hclk_max);
71
72 if (armclk > fclk) {
73 printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
74 armclk = fclk;
75 }
76
77 /* if we are in DVS, we need HCLK to be <= ARMCLK */
78 if (armclk < fclk && armclk < hclk_max)
79 hclk_max = armclk;
80
81 for (hdiv = 1; hdiv < 9; hdiv++) {
82 if (hdiv == 5 || hdiv == 7)
83 hdiv++;
84
85 hclk = (fclk / hdiv);
86 if (hclk <= hclk_max || within_khz(hclk, hclk_max))
87 break;
88 }
89
90 s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
91
92 if (hdiv > 8)
93 goto invalid;
94
95 pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
96
97 if ((hclk / pdiv) > cfg->max.pclk)
98 pdiv++;
99
100 s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
101
102 if (pdiv > 2)
103 goto invalid;
104
105 pdiv *= hdiv;
106
107 /* calculate a valid armclk */
108
109 if (armclk < hclk)
110 armclk = hclk;
111
112 /* if we're running armclk lower than fclk, this really means
113 * that the system should go into dvs mode, which means that
114 * armclk is connected to hclk. */
115 if (armclk < fclk) {
116 cfg->divs.dvs = 1;
117 armclk = hclk;
118 } else
119 cfg->divs.dvs = 0;
120
121 cfg->freq.armclk = armclk;
122
123 /* store the result, and then return */
124
125 cfg->divs.h_divisor = hdiv;
126 cfg->divs.p_divisor = pdiv;
127
128 return 0;
129
130 invalid:
131 return -EINVAL;
132}
133
134#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
135 S3C2440_CAMDIVN_HCLK4_HALF)
136
137/**
138 * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
139 * @cfg: The cpu frequency settings.
140 *
141 * Set the divisors from the settings in @cfg, which where generated
142 * during the calculation phase by s3c2440_cpufreq_calcdivs().
143 */
144static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
145{
146 unsigned long clkdiv, camdiv;
147
148 s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
149 cfg->divs.h_divisor, cfg->divs.p_divisor);
150
151 clkdiv = __raw_readl(S3C2410_CLKDIVN);
152 camdiv = __raw_readl(S3C2440_CAMDIVN);
153
154 clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
155 camdiv &= ~CAMDIVN_HCLK_HALF;
156
157 switch (cfg->divs.h_divisor) {
158 case 1:
159 clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
160 break;
161
162 case 2:
163 clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
164 break;
165
166 case 6:
167 camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
168 case 3:
169 clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
170 break;
171
172 case 8:
173 camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
174 case 4:
175 clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
176 break;
177
178 default:
179 BUG(); /* we don't expect to get here. */
180 }
181
182 if (cfg->divs.p_divisor != cfg->divs.h_divisor)
183 clkdiv |= S3C2440_CLKDIVN_PDIVN;
184
185 /* todo - set pclk. */
186
187 /* Write the divisors first with hclk intentionally halved so that
188 * when we write clkdiv we will under-frequency instead of over. We
189 * then make a short delay and remove the hclk halving if necessary.
190 */
191
192 __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
193 __raw_writel(clkdiv, S3C2410_CLKDIVN);
194
195 ndelay(20);
196 __raw_writel(camdiv, S3C2440_CAMDIVN);
197
198 clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
199}
200
201static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
202 int *divs,
203 struct cpufreq_frequency_table *table,
204 size_t table_size)
205{
206 unsigned long freq;
207 int index = 0;
208 int div;
209
210 for (div = *divs; div > 0; div = *divs++) {
211 freq = fclk / div;
212
213 if (freq > max_hclk && div != 1)
214 continue;
215
216 freq /= 1000; /* table is in kHz */
217 index = s3c_cpufreq_addfreq(table, index, table_size, freq);
218 if (index < 0)
219 break;
220 }
221
222 return index;
223}
224
225static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
226
227static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
228 struct cpufreq_frequency_table *table,
229 size_t table_size)
230{
231 int ret;
232
233 WARN_ON(cfg->info == NULL);
234 WARN_ON(cfg->board == NULL);
235
236 ret = run_freq_for(cfg->info->max.hclk,
237 cfg->info->max.fclk,
238 hclk_divs,
239 table, table_size);
240
241 s3c_freq_dbg("%s: returning %d\n", __func__, ret);
242
243 return ret;
244}
245
246struct s3c_cpufreq_info s3c2440_cpufreq_info = {
247 .max = {
248 .fclk = 400000000,
249 .hclk = 133333333,
250 .pclk = 66666666,
251 },
252
253 .locktime_m = 300,
254 .locktime_u = 300,
255 .locktime_bits = 16,
256
257 .name = "s3c244x",
258 .calc_iotiming = s3c2410_iotiming_calc,
259 .set_iotiming = s3c2410_iotiming_set,
260 .get_iotiming = s3c2410_iotiming_get,
261 .set_fvco = s3c2410_set_fvco,
262
263 .set_refresh = s3c2410_cpufreq_setrefresh,
264 .set_divs = s3c2440_cpufreq_setdivs,
265 .calc_divs = s3c2440_cpufreq_calcdivs,
266 .calc_freqtable = s3c2440_cpufreq_calctable,
267
268 .resume_clocks = s3c244x_setup_clocks,
269
270 .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
271};
272
273static int s3c2440_cpufreq_add(struct sys_device *sysdev)
274{
275 xtal = s3c_cpufreq_clk_get(NULL, "xtal");
276 hclk = s3c_cpufreq_clk_get(NULL, "hclk");
277 fclk = s3c_cpufreq_clk_get(NULL, "fclk");
278 armclk = s3c_cpufreq_clk_get(NULL, "armclk");
279
280 if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
281 printk(KERN_ERR "%s: failed to get clocks\n", __func__);
282 return -ENOENT;
283 }
284
285 return s3c_cpufreq_register(&s3c2440_cpufreq_info);
286}
287
288static struct sysdev_driver s3c2440_cpufreq_driver = {
289 .add = s3c2440_cpufreq_add,
290};
291
292static int s3c2440_cpufreq_init(void)
293{
294 return sysdev_driver_register(&s3c2440_sysclass,
295 &s3c2440_cpufreq_driver);
296}
297
298/* arch_initcall adds the clocks we need, so use subsys_initcall. */
299subsys_initcall(s3c2440_cpufreq_init);
300
301static struct sysdev_driver s3c2442_cpufreq_driver = {
302 .add = s3c2440_cpufreq_add,
303};
304
305static int s3c2442_cpufreq_init(void)
306{
307 return sysdev_driver_register(&s3c2442_sysclass,
308 &s3c2442_cpufreq_driver);
309}
310
311subsys_initcall(s3c2442_cpufreq_init);
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
new file mode 100644
index 000000000000..ff9443b233aa
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
@@ -0,0 +1,97 @@
1/* arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
2 *
3 * Copyright (c) 2006,2007 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 * Vincent Sanders <vince@arm.linux.org.uk>
7 *
8 * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/sysdev.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20
21#include <plat/cpu.h>
22#include <plat/cpu-freq-core.h>
23
24static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
25 { .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
26 { .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
27 { .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
28 { .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
29 { .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
30 { .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
31 { .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
32 { .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
33 { .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
34 { .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
35 { .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
36 { .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
37 { .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
38 { .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
39 { .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
40 { .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
41 { .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
42 { .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
43 { .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
44 { .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
45 { .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
46 { .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
47 { .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
48 { .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
49 { .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
50 { .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
51 { .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
52};
53
54static int s3c2440_plls12_add(struct sys_device *dev)
55{
56 struct clk *xtal_clk;
57 unsigned long xtal;
58
59 xtal_clk = clk_get(NULL, "xtal");
60 if (IS_ERR(xtal_clk))
61 return PTR_ERR(xtal_clk);
62
63 xtal = clk_get_rate(xtal_clk);
64 clk_put(xtal_clk);
65
66 if (xtal == 12000000) {
67 printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
68 return s3c_plltab_register(s3c2440_plls_12,
69 ARRAY_SIZE(s3c2440_plls_12));
70 }
71
72 return 0;
73}
74
75static struct sysdev_driver s3c2440_plls12_drv = {
76 .add = s3c2440_plls12_add,
77};
78
79static int __init s3c2440_pll_12mhz(void)
80{
81 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
82
83}
84
85arch_initcall(s3c2440_pll_12mhz);
86
87static struct sysdev_driver s3c2442_plls12_drv = {
88 .add = s3c2440_plls12_add,
89};
90
91static int __init s3c2442_pll_12mhz(void)
92{
93 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
94
95}
96
97arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
new file mode 100644
index 000000000000..7679af13a94d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
@@ -0,0 +1,127 @@
1/* arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
2 *
3 * Copyright (c) 2006-2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 * Vincent Sanders <vince@arm.linux.org.uk>
7 *
8 * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/sysdev.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20
21#include <plat/cpu.h>
22#include <plat/cpu-freq-core.h>
23
24static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
25 { .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
26 { .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
27 { .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
28 { .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
29 { .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
30 { .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
31 { .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
32 { .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
33 { .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
34 { .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
35 { .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
36 { .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
37 { .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
38 { .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
39 { .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
40 { .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
41 { .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
42 { .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
43 { .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
44 { .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
45 { .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
46 { .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
47 { .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
48 { .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
49 { .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
50 { .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
51 { .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
52 { .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
53 { .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
54 { .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
55 { .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
56 { .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
57 { .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
58 { .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
59 { .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
60 { .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
61 { .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
62 { .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
63 { .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
64 { .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
65 { .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
66 { .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
67 { .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
68 { .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
69 { .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
70 { .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
71 { .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
72 { .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
73 { .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
74 { .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
75 { .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
76 { .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
77 { .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
78 { .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
79 { .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
80};
81
82static int s3c2440_plls169344_add(struct sys_device *dev)
83{
84 struct clk *xtal_clk;
85 unsigned long xtal;
86
87 xtal_clk = clk_get(NULL, "xtal");
88 if (IS_ERR(xtal_clk))
89 return PTR_ERR(xtal_clk);
90
91 xtal = clk_get_rate(xtal_clk);
92 clk_put(xtal_clk);
93
94 if (xtal == 169344000) {
95 printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
96 return s3c_plltab_register(s3c2440_plls_169344,
97 ARRAY_SIZE(s3c2440_plls_169344));
98 }
99
100 return 0;
101}
102
103static struct sysdev_driver s3c2440_plls169344_drv = {
104 .add = s3c2440_plls169344_add,
105};
106
107static int __init s3c2440_pll_16934400(void)
108{
109 return sysdev_driver_register(&s3c2440_sysclass,
110 &s3c2440_plls169344_drv);
111
112}
113
114arch_initcall(s3c2440_pll_16934400);
115
116static struct sysdev_driver s3c2442_plls169344_drv = {
117 .add = s3c2440_plls169344_add,
118};
119
120static int __init s3c2442_pll_16934400(void)
121{
122 return sysdev_driver_register(&s3c2442_sysclass,
123 &s3c2442_plls169344_drv);
124
125}
126
127arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
new file mode 100644
index 000000000000..89fcf5308cf6
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -0,0 +1,38 @@
1/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpd8_9_10.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * S3C24XX SPI - gpio configuration for bus 1 on gpd8,9,10
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License.
12*/
13
14#include <linux/kernel.h>
15#include <linux/gpio.h>
16
17#include <mach/spi.h>
18#include <mach/regs-gpio.h>
19
20void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
21 int enable)
22{
23
24 printk(KERN_INFO "%s(%d)\n", __func__, enable);
25 if (enable) {
26 s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
27 s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
28 s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
29 s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
30 s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
31 } else {
32 s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
33 s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
34 s3c2410_gpio_pullup(S3C2410_GPD(10), 1);
35 s3c2410_gpio_pullup(S3C2410_GPD(9), 1);
36 s3c2410_gpio_pullup(S3C2410_GPD(8), 1);
37 }
38}
diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig
index 5ebd8b425a54..bcfa778614d8 100644
--- a/arch/arm/plat-s3c64xx/Kconfig
+++ b/arch/arm/plat-s3c64xx/Kconfig
@@ -19,6 +19,7 @@ config PLAT_S3C64XX
19 select S3C_GPIO_PULL_UPDOWN 19 select S3C_GPIO_PULL_UPDOWN
20 select S3C_GPIO_CFG_S3C24XX 20 select S3C_GPIO_CFG_S3C24XX
21 select S3C_GPIO_CFG_S3C64XX 21 select S3C_GPIO_CFG_S3C64XX
22 select S3C_DEV_NAND
22 select USB_ARCH_HAS_OHCI 23 select USB_ARCH_HAS_OHCI
23 help 24 help
24 Base platform code for any Samsung S3C64XX device 25 Base platform code for any Samsung S3C64XX device
diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile
index 3c8882cd6268..b85b4359e935 100644
--- a/arch/arm/plat-s3c64xx/Makefile
+++ b/arch/arm/plat-s3c64xx/Makefile
@@ -40,4 +40,5 @@ obj-$(CONFIG_S3C64XX_DMA) += dma.o
40obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o 40obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
41obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o 41obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
42obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o 42obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
43obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o \ No newline at end of file 43obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
44obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o
diff --git a/arch/arm/plat-s3c/dev-audio.c b/arch/arm/plat-s3c64xx/dev-audio.c
index 1322beb40dd7..1322beb40dd7 100644
--- a/arch/arm/plat-s3c/dev-audio.c
+++ b/arch/arm/plat-s3c64xx/dev-audio.c
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
new file mode 100644
index 000000000000..a8a711c3c064
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -0,0 +1,50 @@
1# arch/arm/plat-s5pc1xx/Kconfig
2#
3# Copyright 2009 Samsung Electronics Co.
4# Byungho Min <bhmin@samsung.com>
5#
6# Licensed under GPLv2
7
8config PLAT_S5PC1XX
9 bool
10 depends on ARCH_S5PC1XX
11 default y
12 select PLAT_S3C
13 select ARM_VIC
14 select NO_IOPORT
15 select ARCH_REQUIRE_GPIOLIB
16 select S3C_GPIO_TRACK
17 select S3C_GPIO_PULL_UPDOWN
18 help
19 Base platform code for any Samsung S5PC1XX device
20
21if PLAT_S5PC1XX
22
23# Configuration options shared by all S3C64XX implementations
24
25config CPU_S5PC100_INIT
26 bool
27 help
28 Common initialisation code for the S5PC1XX
29
30config CPU_S5PC100_CLOCK
31 bool
32 help
33 Common clock support code for the S5PC1XX
34
35# platform specific device setup
36
37config S5PC100_SETUP_I2C0
38 bool
39 default y
40 help
41 Common setup code for i2c bus 0.
42
43 Note, currently since i2c0 is always compiled, this setup helper
44 is always compiled with it.
45
46config S5PC100_SETUP_I2C1
47 bool
48 help
49 Common setup code for i2c bus 1.
50endif
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
new file mode 100644
index 000000000000..f1ecb2c37ee2
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -0,0 +1,26 @@
1# arch/arm/plat-s5pc1xx/Makefile
2#
3# Copyright 2009 Samsung Electronics Co.
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n := dummy.o
10obj- :=
11
12# Core files
13
14obj-y += dev-uart.o
15obj-y += cpu.o
16obj-y += irq.o
17
18# CPU support
19
20obj-$(CONFIG_CPU_S5PC100_INIT) += s5pc100-init.o
21obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-clock.o
22
23# Device setup
24
25obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
26obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
new file mode 100644
index 000000000000..715a7330794d
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -0,0 +1,112 @@
1/* linux/arch/arm/plat-s5pc1xx/cpu.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX CPU Support
7 *
8 * Based on plat-s3c64xx/cpu.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/serial_core.h>
20#include <linux/platform_device.h>
21#include <linux/io.h>
22
23#include <mach/hardware.h>
24#include <mach/map.h>
25
26#include <asm/mach/map.h>
27
28#include <plat/regs-serial.h>
29
30#include <plat/cpu.h>
31#include <plat/devs.h>
32#include <plat/clock.h>
33
34#include <plat/s5pc100.h>
35
36/* table of supported CPUs */
37
38static const char name_s5pc100[] = "S5PC100";
39
40static struct cpu_table cpu_ids[] __initdata = {
41 {
42 .idcode = 0x43100000,
43 .idmask = 0xfffff000,
44 .map_io = s5pc100_map_io,
45 .init_clocks = s5pc100_init_clocks,
46 .init_uarts = s5pc100_init_uarts,
47 .init = s5pc100_init,
48 .name = name_s5pc100,
49 },
50};
51/* minimal IO mapping */
52
53/* see notes on uart map in arch/arm/mach-s5pc100/include/mach/debug-macro.S */
54#define UART_OFFS (S3C_PA_UART & 0xffff)
55
56static struct map_desc s5pc1xx_iodesc[] __initdata = {
57 {
58 .virtual = (unsigned long)S5PC1XX_VA_CHIPID,
59 .pfn = __phys_to_pfn(S5PC1XX_PA_CHIPID),
60 .length = SZ_16,
61 .type = MT_DEVICE,
62 }, {
63 .virtual = (unsigned long)S5PC1XX_VA_CLK,
64 .pfn = __phys_to_pfn(S5PC1XX_PA_CLK),
65 .length = SZ_4K,
66 .type = MT_DEVICE,
67 }, {
68 .virtual = (unsigned long)S5PC1XX_VA_PWR,
69 .pfn = __phys_to_pfn(S5PC1XX_PA_PWR),
70 .length = SZ_4K,
71 .type = MT_DEVICE,
72 }, {
73 .virtual = (unsigned long)(S5PC1XX_VA_UART),
74 .pfn = __phys_to_pfn(S5PC1XX_PA_UART),
75 .length = SZ_4K,
76 .type = MT_DEVICE,
77 }, {
78 .virtual = (unsigned long)S5PC1XX_VA_VIC(0),
79 .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(0)),
80 .length = SZ_4K,
81 .type = MT_DEVICE,
82 }, {
83 .virtual = (unsigned long)S5PC1XX_VA_VIC(1),
84 .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(1)),
85 .length = SZ_4K,
86 .type = MT_DEVICE,
87 }, {
88 .virtual = (unsigned long)S5PC1XX_VA_VIC(2),
89 .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(2)),
90 .length = SZ_4K,
91 .type = MT_DEVICE,
92 }, {
93 .virtual = (unsigned long)S5PC1XX_VA_TIMER,
94 .pfn = __phys_to_pfn(S5PC1XX_PA_TIMER),
95 .length = SZ_256,
96 .type = MT_DEVICE,
97 },
98};
99
100/* read cpu identification code */
101
102void __init s5pc1xx_init_io(struct map_desc *mach_desc, int size)
103{
104 unsigned long idcode;
105
106 /* initialise the io descriptors we need for initialisation */
107 iotable_init(s5pc1xx_iodesc, ARRAY_SIZE(s5pc1xx_iodesc));
108 iotable_init(mach_desc, size);
109
110 idcode = __raw_readl(S5PC1XX_VA_CHIPID);
111 s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
112}
diff --git a/arch/arm/plat-s5pc1xx/dev-uart.c b/arch/arm/plat-s5pc1xx/dev-uart.c
new file mode 100644
index 000000000000..f749bc5407b5
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/dev-uart.c
@@ -0,0 +1,174 @@
1/* linux/arch/arm/plat-s5pc1xx/dev-uart.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Based on plat-s3c64xx/dev-uart.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/platform_device.h>
19
20#include <asm/mach/arch.h>
21#include <asm/mach/irq.h>
22#include <mach/hardware.h>
23#include <mach/map.h>
24
25#include <plat/devs.h>
26
27/* Serial port registrations */
28
29/* 64xx uarts are closer together */
30
31static struct resource s5pc1xx_uart0_resource[] = {
32 [0] = {
33 .start = S3C_PA_UART0,
34 .end = S3C_PA_UART0 + 0x100,
35 .flags = IORESOURCE_MEM,
36 },
37 [1] = {
38 .start = IRQ_S3CUART_RX0,
39 .end = IRQ_S3CUART_RX0,
40 .flags = IORESOURCE_IRQ,
41 },
42 [2] = {
43 .start = IRQ_S3CUART_TX0,
44 .end = IRQ_S3CUART_TX0,
45 .flags = IORESOURCE_IRQ,
46
47 },
48 [3] = {
49 .start = IRQ_S3CUART_ERR0,
50 .end = IRQ_S3CUART_ERR0,
51 .flags = IORESOURCE_IRQ,
52 }
53};
54
55static struct resource s5pc1xx_uart1_resource[] = {
56 [0] = {
57 .start = S3C_PA_UART1,
58 .end = S3C_PA_UART1 + 0x100,
59 .flags = IORESOURCE_MEM,
60 },
61 [1] = {
62 .start = IRQ_S3CUART_RX1,
63 .end = IRQ_S3CUART_RX1,
64 .flags = IORESOURCE_IRQ,
65 },
66 [2] = {
67 .start = IRQ_S3CUART_TX1,
68 .end = IRQ_S3CUART_TX1,
69 .flags = IORESOURCE_IRQ,
70
71 },
72 [3] = {
73 .start = IRQ_S3CUART_ERR1,
74 .end = IRQ_S3CUART_ERR1,
75 .flags = IORESOURCE_IRQ,
76 },
77};
78
79static struct resource s5pc1xx_uart2_resource[] = {
80 [0] = {
81 .start = S3C_PA_UART2,
82 .end = S3C_PA_UART2 + 0x100,
83 .flags = IORESOURCE_MEM,
84 },
85 [1] = {
86 .start = IRQ_S3CUART_RX2,
87 .end = IRQ_S3CUART_RX2,
88 .flags = IORESOURCE_IRQ,
89 },
90 [2] = {
91 .start = IRQ_S3CUART_TX2,
92 .end = IRQ_S3CUART_TX2,
93 .flags = IORESOURCE_IRQ,
94
95 },
96 [3] = {
97 .start = IRQ_S3CUART_ERR2,
98 .end = IRQ_S3CUART_ERR2,
99 .flags = IORESOURCE_IRQ,
100 },
101};
102
103static struct resource s5pc1xx_uart3_resource[] = {
104 [0] = {
105 .start = S3C_PA_UART3,
106 .end = S3C_PA_UART3 + 0x100,
107 .flags = IORESOURCE_MEM,
108 },
109 [1] = {
110 .start = IRQ_S3CUART_RX3,
111 .end = IRQ_S3CUART_RX3,
112 .flags = IORESOURCE_IRQ,
113 },
114 [2] = {
115 .start = IRQ_S3CUART_TX3,
116 .end = IRQ_S3CUART_TX3,
117 .flags = IORESOURCE_IRQ,
118
119 },
120 [3] = {
121 .start = IRQ_S3CUART_ERR3,
122 .end = IRQ_S3CUART_ERR3,
123 .flags = IORESOURCE_IRQ,
124 },
125};
126
127
128struct s3c24xx_uart_resources s5pc1xx_uart_resources[] __initdata = {
129 [0] = {
130 .resources = s5pc1xx_uart0_resource,
131 .nr_resources = ARRAY_SIZE(s5pc1xx_uart0_resource),
132 },
133 [1] = {
134 .resources = s5pc1xx_uart1_resource,
135 .nr_resources = ARRAY_SIZE(s5pc1xx_uart1_resource),
136 },
137 [2] = {
138 .resources = s5pc1xx_uart2_resource,
139 .nr_resources = ARRAY_SIZE(s5pc1xx_uart2_resource),
140 },
141 [3] = {
142 .resources = s5pc1xx_uart3_resource,
143 .nr_resources = ARRAY_SIZE(s5pc1xx_uart3_resource),
144 },
145};
146
147/* uart devices */
148
149static struct platform_device s3c24xx_uart_device0 = {
150 .id = 0,
151};
152
153static struct platform_device s3c24xx_uart_device1 = {
154 .id = 1,
155};
156
157static struct platform_device s3c24xx_uart_device2 = {
158 .id = 2,
159};
160
161static struct platform_device s3c24xx_uart_device3 = {
162 .id = 3,
163};
164
165struct platform_device *s3c24xx_uart_src[4] = {
166 &s3c24xx_uart_device0,
167 &s3c24xx_uart_device1,
168 &s3c24xx_uart_device2,
169 &s3c24xx_uart_device3,
170};
171
172struct platform_device *s3c24xx_uart_devs[4] = {
173};
174
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
new file mode 100644
index 000000000000..f07d8c3b25d6
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
@@ -0,0 +1,182 @@
1/* linux/arch/arm/plat-s5pc1xx/include/plat/irqs.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX - Common IRQ support
7 *
8 * Based on plat-s3c64xx/include/plat/irqs.h
9 */
10
11#ifndef __ASM_PLAT_S5PC1XX_IRQS_H
12#define __ASM_PLAT_S5PC1XX_IRQS_H __FILE__
13
14/* we keep the first set of CPU IRQs out of the range of
15 * the ISA space, so that the PC104 has them to itself
16 * and we don't end up having to do horrible things to the
17 * standard ISA drivers....
18 *
19 * note, since we're using the VICs, our start must be a
20 * mulitple of 32 to allow the common code to work
21 */
22
23#define S3C_IRQ_OFFSET (32)
24
25#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
26
27#define S3C_VIC0_BASE S3C_IRQ(0)
28#define S3C_VIC1_BASE S3C_IRQ(32)
29#define S3C_VIC2_BASE S3C_IRQ(64)
30
31/* UART interrupts, each UART has 4 intterupts per channel so
32 * use the space between the ISA and S3C main interrupts. Note, these
33 * are not in the same order as the S3C24XX series! */
34
35#define IRQ_S3CUART_BASE0 (16)
36#define IRQ_S3CUART_BASE1 (20)
37#define IRQ_S3CUART_BASE2 (24)
38#define IRQ_S3CUART_BASE3 (28)
39
40#define UART_IRQ_RXD (0)
41#define UART_IRQ_ERR (1)
42#define UART_IRQ_TXD (2)
43#define UART_IRQ_MODEM (3)
44
45#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
46#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
47#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
48
49#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
50#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
51#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
52
53#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
54#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
55#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
56
57#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
58#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
59#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
60
61/* VIC based IRQs */
62
63#define S5PC1XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x))
64#define S5PC1XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x))
65#define S5PC1XX_IRQ_VIC2(x) (S3C_VIC2_BASE + (x))
66
67/*
68 * VIC0: system, DMA, timer
69 */
70#define IRQ_EINT0 S5PC1XX_IRQ_VIC0(0)
71#define IRQ_EINT1 S5PC1XX_IRQ_VIC0(1)
72#define IRQ_EINT2 S5PC1XX_IRQ_VIC0(2)
73#define IRQ_EINT3 S5PC1XX_IRQ_VIC0(3)
74#define IRQ_EINT4 S5PC1XX_IRQ_VIC0(4)
75#define IRQ_EINT5 S5PC1XX_IRQ_VIC0(5)
76#define IRQ_EINT6 S5PC1XX_IRQ_VIC0(6)
77#define IRQ_EINT7 S5PC1XX_IRQ_VIC0(7)
78#define IRQ_EINT8 S5PC1XX_IRQ_VIC0(8)
79#define IRQ_EINT9 S5PC1XX_IRQ_VIC0(9)
80#define IRQ_EINT10 S5PC1XX_IRQ_VIC0(10)
81#define IRQ_EINT11 S5PC1XX_IRQ_VIC0(11)
82#define IRQ_EINT12 S5PC1XX_IRQ_VIC0(12)
83#define IRQ_EINT13 S5PC1XX_IRQ_VIC0(13)
84#define IRQ_EINT14 S5PC1XX_IRQ_VIC0(14)
85#define IRQ_EINT15 S5PC1XX_IRQ_VIC0(15)
86#define IRQ_EINT16_31 S5PC1XX_IRQ_VIC0(16)
87#define IRQ_BATF S5PC1XX_IRQ_VIC0(17)
88#define IRQ_MDMA S5PC1XX_IRQ_VIC0(18)
89#define IRQ_PDMA0 S5PC1XX_IRQ_VIC0(19)
90#define IRQ_PDMA1 S5PC1XX_IRQ_VIC0(20)
91#define IRQ_TIMER0 S5PC1XX_IRQ_VIC0(21)
92#define IRQ_TIMER1 S5PC1XX_IRQ_VIC0(22)
93#define IRQ_TIMER2 S5PC1XX_IRQ_VIC0(23)
94#define IRQ_TIMER3 S5PC1XX_IRQ_VIC0(24)
95#define IRQ_TIMER4 S5PC1XX_IRQ_VIC0(25)
96#define IRQ_SYSTIMER S5PC1XX_IRQ_VIC0(26)
97#define IRQ_WDT S5PC1XX_IRQ_VIC0(27)
98#define IRQ_RTC_ALARM S5PC1XX_IRQ_VIC0(28)
99#define IRQ_RTC_TIC S5PC1XX_IRQ_VIC0(29)
100#define IRQ_GPIOINT S5PC1XX_IRQ_VIC0(30)
101
102/*
103 * VIC1: ARM, power, memory, connectivity
104 */
105#define IRQ_CORTEX0 S5PC1XX_IRQ_VIC1(0)
106#define IRQ_CORTEX1 S5PC1XX_IRQ_VIC1(1)
107#define IRQ_CORTEX2 S5PC1XX_IRQ_VIC1(2)
108#define IRQ_CORTEX3 S5PC1XX_IRQ_VIC1(3)
109#define IRQ_CORTEX4 S5PC1XX_IRQ_VIC1(4)
110#define IRQ_IEMAPC S5PC1XX_IRQ_VIC1(5)
111#define IRQ_IEMIEC S5PC1XX_IRQ_VIC1(6)
112#define IRQ_ONENAND S5PC1XX_IRQ_VIC1(7)
113#define IRQ_NFC S5PC1XX_IRQ_VIC1(8)
114#define IRQ_CFC S5PC1XX_IRQ_VIC1(9)
115#define IRQ_UART0 S5PC1XX_IRQ_VIC1(10)
116#define IRQ_UART1 S5PC1XX_IRQ_VIC1(11)
117#define IRQ_UART2 S5PC1XX_IRQ_VIC1(12)
118#define IRQ_UART3 S5PC1XX_IRQ_VIC1(13)
119#define IRQ_IIC S5PC1XX_IRQ_VIC1(14)
120#define IRQ_SPI0 S5PC1XX_IRQ_VIC1(15)
121#define IRQ_SPI1 S5PC1XX_IRQ_VIC1(16)
122#define IRQ_SPI2 S5PC1XX_IRQ_VIC1(17)
123#define IRQ_IRDA S5PC1XX_IRQ_VIC1(18)
124#define IRQ_CAN0 S5PC1XX_IRQ_VIC1(19)
125#define IRQ_CAN1 S5PC1XX_IRQ_VIC1(20)
126#define IRQ_HSIRX S5PC1XX_IRQ_VIC1(21)
127#define IRQ_HSITX S5PC1XX_IRQ_VIC1(22)
128#define IRQ_UHOST S5PC1XX_IRQ_VIC1(23)
129#define IRQ_OTG S5PC1XX_IRQ_VIC1(24)
130#define IRQ_MSM S5PC1XX_IRQ_VIC1(25)
131#define IRQ_HSMMC0 S5PC1XX_IRQ_VIC1(26)
132#define IRQ_HSMMC1 S5PC1XX_IRQ_VIC1(27)
133#define IRQ_HSMMC2 S5PC1XX_IRQ_VIC1(28)
134#define IRQ_MIPICSI S5PC1XX_IRQ_VIC1(29)
135#define IRQ_MIPIDSI S5PC1XX_IRQ_VIC1(30)
136
137/*
138 * VIC2: multimedia, audio, security
139 */
140#define IRQ_LCD0 S5PC1XX_IRQ_VIC2(0)
141#define IRQ_LCD1 S5PC1XX_IRQ_VIC2(1)
142#define IRQ_LCD2 S5PC1XX_IRQ_VIC2(2)
143#define IRQ_LCD3 S5PC1XX_IRQ_VIC2(3)
144#define IRQ_ROTATOR S5PC1XX_IRQ_VIC2(4)
145#define IRQ_FIMC0 S5PC1XX_IRQ_VIC2(5)
146#define IRQ_FIMC1 S5PC1XX_IRQ_VIC2(6)
147#define IRQ_FIMC2 S5PC1XX_IRQ_VIC2(7)
148#define IRQ_JPEG S5PC1XX_IRQ_VIC2(8)
149#define IRQ_2D S5PC1XX_IRQ_VIC2(9)
150#define IRQ_3D S5PC1XX_IRQ_VIC2(10)
151#define IRQ_MIXER S5PC1XX_IRQ_VIC2(11)
152#define IRQ_HDMI S5PC1XX_IRQ_VIC2(12)
153#define IRQ_IIC1 S5PC1XX_IRQ_VIC2(13)
154#define IRQ_MFC S5PC1XX_IRQ_VIC2(14)
155#define IRQ_TVENC S5PC1XX_IRQ_VIC2(15)
156#define IRQ_I2S0 S5PC1XX_IRQ_VIC2(16)
157#define IRQ_I2S1 S5PC1XX_IRQ_VIC2(17)
158#define IRQ_I2S2 S5PC1XX_IRQ_VIC2(18)
159#define IRQ_AC97 S5PC1XX_IRQ_VIC2(19)
160#define IRQ_PCM0 S5PC1XX_IRQ_VIC2(20)
161#define IRQ_PCM1 S5PC1XX_IRQ_VIC2(21)
162#define IRQ_SPDIF S5PC1XX_IRQ_VIC2(22)
163#define IRQ_ADC S5PC1XX_IRQ_VIC2(23)
164#define IRQ_PENDN S5PC1XX_IRQ_VIC2(24)
165#define IRQ_TC IRQ_PENDN
166#define IRQ_KEYPAD S5PC1XX_IRQ_VIC2(25)
167#define IRQ_CG S5PC1XX_IRQ_VIC2(26)
168#define IRQ_SEC S5PC1XX_IRQ_VIC2(27)
169#define IRQ_SECRX S5PC1XX_IRQ_VIC2(28)
170#define IRQ_SECTX S5PC1XX_IRQ_VIC2(29)
171#define IRQ_SDMIRQ S5PC1XX_IRQ_VIC2(30)
172#define IRQ_SDMFIQ S5PC1XX_IRQ_VIC2(31)
173
174#define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 1)
175
176#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
177#define IRQ_EINT(x) S3C_EINT(x)
178
179#define NR_IRQS (IRQ_EINT(31)+1)
180
181#endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
182
diff --git a/arch/arm/plat-s5pc1xx/include/plat/pll.h b/arch/arm/plat-s5pc1xx/include/plat/pll.h
new file mode 100644
index 000000000000..21afef1573e7
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/pll.h
@@ -0,0 +1,38 @@
1/* arch/arm/plat-s5pc1xx/include/plat/pll.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX PLL code
7 *
8 * Based on plat-s3c64xx/include/plat/pll.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#define S5P_PLL_MDIV_MASK ((1 << (25-16+1)) - 1)
16#define S5P_PLL_PDIV_MASK ((1 << (13-8+1)) - 1)
17#define S5P_PLL_SDIV_MASK ((1 << (2-0+1)) - 1)
18#define S5P_PLL_MDIV_SHIFT (16)
19#define S5P_PLL_PDIV_SHIFT (8)
20#define S5P_PLL_SDIV_SHIFT (0)
21
22#include <asm/div64.h>
23
24static inline unsigned long s5pc1xx_get_pll(unsigned long baseclk,
25 u32 pllcon)
26{
27 u32 mdiv, pdiv, sdiv;
28 u64 fvco = baseclk;
29
30 mdiv = (pllcon >> S5P_PLL_MDIV_SHIFT) & S5P_PLL_MDIV_MASK;
31 pdiv = (pllcon >> S5P_PLL_PDIV_SHIFT) & S5P_PLL_PDIV_MASK;
32 sdiv = (pllcon >> S5P_PLL_SDIV_SHIFT) & S5P_PLL_SDIV_MASK;
33
34 fvco *= mdiv;
35 do_div(fvco, (pdiv << sdiv));
36
37 return (unsigned long)fvco;
38}
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
new file mode 100644
index 000000000000..75c8390cb827
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
@@ -0,0 +1,421 @@
1/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX clock register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __PLAT_REGS_CLOCK_H
14#define __PLAT_REGS_CLOCK_H __FILE__
15
16#define S5PC1XX_CLKREG(x) (S5PC1XX_VA_CLK + (x))
17
18#define S5PC1XX_APLL_LOCK S5PC1XX_CLKREG(0x00)
19#define S5PC1XX_MPLL_LOCK S5PC1XX_CLKREG(0x04)
20#define S5PC1XX_EPLL_LOCK S5PC1XX_CLKREG(0x08)
21#define S5PC100_HPLL_LOCK S5PC1XX_CLKREG(0x0C)
22
23#define S5PC1XX_APLL_CON S5PC1XX_CLKREG(0x100)
24#define S5PC1XX_MPLL_CON S5PC1XX_CLKREG(0x104)
25#define S5PC1XX_EPLL_CON S5PC1XX_CLKREG(0x108)
26#define S5PC100_HPLL_CON S5PC1XX_CLKREG(0x10C)
27
28#define S5PC1XX_CLK_SRC0 S5PC1XX_CLKREG(0x200)
29#define S5PC1XX_CLK_SRC1 S5PC1XX_CLKREG(0x204)
30#define S5PC1XX_CLK_SRC2 S5PC1XX_CLKREG(0x208)
31#define S5PC1XX_CLK_SRC3 S5PC1XX_CLKREG(0x20C)
32
33#define S5PC1XX_CLK_DIV0 S5PC1XX_CLKREG(0x300)
34#define S5PC1XX_CLK_DIV1 S5PC1XX_CLKREG(0x304)
35#define S5PC1XX_CLK_DIV2 S5PC1XX_CLKREG(0x308)
36#define S5PC1XX_CLK_DIV3 S5PC1XX_CLKREG(0x30C)
37#define S5PC1XX_CLK_DIV4 S5PC1XX_CLKREG(0x310)
38
39#define S5PC100_CLK_OUT S5PC1XX_CLKREG(0x400)
40
41#define S5PC100_CLKGATE_D00 S5PC1XX_CLKREG(0x500)
42#define S5PC100_CLKGATE_D01 S5PC1XX_CLKREG(0x504)
43#define S5PC100_CLKGATE_D02 S5PC1XX_CLKREG(0x508)
44
45#define S5PC100_CLKGATE_D10 S5PC1XX_CLKREG(0x520)
46#define S5PC100_CLKGATE_D11 S5PC1XX_CLKREG(0x524)
47#define S5PC100_CLKGATE_D12 S5PC1XX_CLKREG(0x528)
48#define S5PC100_CLKGATE_D13 S5PC1XX_CLKREG(0x52C)
49#define S5PC100_CLKGATE_D14 S5PC1XX_CLKREG(0x530)
50#define S5PC100_CLKGATE_D15 S5PC1XX_CLKREG(0x534)
51
52#define S5PC100_CLKGATE_D20 S5PC1XX_CLKREG(0x540)
53
54#define S5PC100_SCLKGATE0 S5PC1XX_CLKREG(0x560)
55#define S5PC100_SCLKGATE1 S5PC1XX_CLKREG(0x564)
56
57#define S5PC100_OTHERS S5PC1XX_CLKREG(0x8200)
58
59#define S5PC1XX_EPLL_EN (1<<31)
60#define S5PC1XX_EPLL_MASK 0xffffffff
61#define S5PC1XX_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s)))
62
63/* CLKSRC0 */
64#define S5PC1XX_CLKSRC0_APLL_MASK (0x1<<0)
65#define S5PC1XX_CLKSRC0_APLL_SHIFT (0)
66#define S5PC1XX_CLKSRC0_MPLL_MASK (0x1<<4)
67#define S5PC1XX_CLKSRC0_MPLL_SHIFT (4)
68#define S5PC1XX_CLKSRC0_EPLL_MASK (0x1<<8)
69#define S5PC1XX_CLKSRC0_EPLL_SHIFT (8)
70#define S5PC100_CLKSRC0_HPLL_MASK (0x1<<12)
71#define S5PC100_CLKSRC0_HPLL_SHIFT (12)
72#define S5PC100_CLKSRC0_AMMUX_MASK (0x1<<16)
73#define S5PC100_CLKSRC0_AMMUX_SHIFT (16)
74#define S5PC100_CLKSRC0_HREF_MASK (0x1<<20)
75#define S5PC100_CLKSRC0_HREF_SHIFT (20)
76#define S5PC1XX_CLKSRC0_ONENAND_MASK (0x1<<24)
77#define S5PC1XX_CLKSRC0_ONENAND_SHIFT (24)
78
79
80/* CLKSRC1 */
81#define S5PC100_CLKSRC1_UART_MASK (0x1<<0)
82#define S5PC100_CLKSRC1_UART_SHIFT (0)
83#define S5PC100_CLKSRC1_SPI0_MASK (0x3<<4)
84#define S5PC100_CLKSRC1_SPI0_SHIFT (4)
85#define S5PC100_CLKSRC1_SPI1_MASK (0x3<<8)
86#define S5PC100_CLKSRC1_SPI1_SHIFT (8)
87#define S5PC100_CLKSRC1_SPI2_MASK (0x3<<12)
88#define S5PC100_CLKSRC1_SPI2_SHIFT (12)
89#define S5PC100_CLKSRC1_IRDA_MASK (0x3<<16)
90#define S5PC100_CLKSRC1_IRDA_SHIFT (16)
91#define S5PC100_CLKSRC1_UHOST_MASK (0x3<<20)
92#define S5PC100_CLKSRC1_UHOST_SHIFT (20)
93#define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24)
94#define S5PC100_CLKSRC1_CLK48M_SHIFT (24)
95
96/* CLKSRC2 */
97#define S5PC100_CLKSRC2_MMC0_MASK (0x3<<0)
98#define S5PC100_CLKSRC2_MMC0_SHIFT (0)
99#define S5PC100_CLKSRC2_MMC1_MASK (0x3<<4)
100#define S5PC100_CLKSRC2_MMC1_SHIFT (4)
101#define S5PC100_CLKSRC2_MMC2_MASK (0x3<<8)
102#define S5PC100_CLKSRC2_MMC2_SHIFT (8)
103#define S5PC100_CLKSRC2_LCD_MASK (0x3<<12)
104#define S5PC100_CLKSRC2_LCD_SHIFT (12)
105#define S5PC100_CLKSRC2_FIMC0_MASK (0x3<<16)
106#define S5PC100_CLKSRC2_FIMC0_SHIFT (16)
107#define S5PC100_CLKSRC2_FIMC1_MASK (0x3<<20)
108#define S5PC100_CLKSRC2_FIMC1_SHIFT (20)
109#define S5PC100_CLKSRC2_FIMC2_MASK (0x3<<24)
110#define S5PC100_CLKSRC2_FIMC2_SHIFT (24)
111#define S5PC100_CLKSRC2_MIXER_MASK (0x3<<28)
112#define S5PC100_CLKSRC2_MIXER_SHIFT (28)
113
114/* CLKSRC3 */
115#define S5PC100_CLKSRC3_PWI_MASK (0x3<<0)
116#define S5PC100_CLKSRC3_PWI_SHIFT (0)
117#define S5PC100_CLKSRC3_HCLKD2_MASK (0x1<<4)
118#define S5PC100_CLKSRC3_HCLKD2_SHIFT (4)
119#define S5PC100_CLKSRC3_I2SD2_MASK (0x3<<8)
120#define S5PC100_CLKSRC3_I2SD2_SHIFT (8)
121#define S5PC100_CLKSRC3_AUDIO0_MASK (0x7<<12)
122#define S5PC100_CLKSRC3_AUDIO0_SHIFT (12)
123#define S5PC100_CLKSRC3_AUDIO1_MASK (0x7<<16)
124#define S5PC100_CLKSRC3_AUDIO1_SHIFT (16)
125#define S5PC100_CLKSRC3_AUDIO2_MASK (0x7<<20)
126#define S5PC100_CLKSRC3_AUDIO2_SHIFT (20)
127#define S5PC100_CLKSRC3_SPDIF_MASK (0x3<<24)
128#define S5PC100_CLKSRC3_SPDIF_SHIFT (24)
129
130
131/* CLKDIV0 */
132#define S5PC1XX_CLKDIV0_APLL_MASK (0x1<<0)
133#define S5PC1XX_CLKDIV0_APLL_SHIFT (0)
134#define S5PC100_CLKDIV0_ARM_MASK (0x7<<4)
135#define S5PC100_CLKDIV0_ARM_SHIFT (4)
136#define S5PC100_CLKDIV0_D0_MASK (0x7<<8)
137#define S5PC100_CLKDIV0_D0_SHIFT (8)
138#define S5PC100_CLKDIV0_PCLKD0_MASK (0x7<<12)
139#define S5PC100_CLKDIV0_PCLKD0_SHIFT (12)
140#define S5PC100_CLKDIV0_SECSS_MASK (0x7<<16)
141#define S5PC100_CLKDIV0_SECSS_SHIFT (16)
142
143/* CLKDIV1 */
144#define S5PC100_CLKDIV1_AM_MASK (0x7<<0)
145#define S5PC100_CLKDIV1_AM_SHIFT (0)
146#define S5PC100_CLKDIV1_MPLL_MASK (0x3<<4)
147#define S5PC100_CLKDIV1_MPLL_SHIFT (4)
148#define S5PC100_CLKDIV1_MPLL2_MASK (0x1<<8)
149#define S5PC100_CLKDIV1_MPLL2_SHIFT (8)
150#define S5PC100_CLKDIV1_D1_MASK (0x7<<12)
151#define S5PC100_CLKDIV1_D1_SHIFT (12)
152#define S5PC100_CLKDIV1_PCLKD1_MASK (0x7<<16)
153#define S5PC100_CLKDIV1_PCLKD1_SHIFT (16)
154#define S5PC100_CLKDIV1_ONENAND_MASK (0x3<<20)
155#define S5PC100_CLKDIV1_ONENAND_SHIFT (20)
156#define S5PC100_CLKDIV1_CAM_MASK (0x1F<<24)
157#define S5PC100_CLKDIV1_CAM_SHIFT (24)
158
159/* CLKDIV2 */
160#define S5PC100_CLKDIV2_UART_MASK (0x7<<0)
161#define S5PC100_CLKDIV2_UART_SHIFT (0)
162#define S5PC100_CLKDIV2_SPI0_MASK (0xf<<4)
163#define S5PC100_CLKDIV2_SPI0_SHIFT (4)
164#define S5PC100_CLKDIV2_SPI1_MASK (0xf<<8)
165#define S5PC100_CLKDIV2_SPI1_SHIFT (8)
166#define S5PC100_CLKDIV2_SPI2_MASK (0xf<<12)
167#define S5PC100_CLKDIV2_SPI2_SHIFT (12)
168#define S5PC100_CLKDIV2_IRDA_MASK (0xf<<16)
169#define S5PC100_CLKDIV2_IRDA_SHIFT (16)
170#define S5PC100_CLKDIV2_UHOST_MASK (0xf<<20)
171#define S5PC100_CLKDIV2_UHOST_SHIFT (20)
172
173/* CLKDIV3 */
174#define S5PC100_CLKDIV3_MMC0_MASK (0xf<<0)
175#define S5PC100_CLKDIV3_MMC0_SHIFT (0)
176#define S5PC100_CLKDIV3_MMC1_MASK (0xf<<4)
177#define S5PC100_CLKDIV3_MMC1_SHIFT (4)
178#define S5PC100_CLKDIV3_MMC2_MASK (0xf<<8)
179#define S5PC100_CLKDIV3_MMC2_SHIFT (8)
180#define S5PC100_CLKDIV3_LCD_MASK (0xf<<12)
181#define S5PC100_CLKDIV3_LCD_SHIFT (12)
182#define S5PC100_CLKDIV3_FIMC0_MASK (0xf<<16)
183#define S5PC100_CLKDIV3_FIMC0_SHIFT (16)
184#define S5PC100_CLKDIV3_FIMC1_MASK (0xf<<20)
185#define S5PC100_CLKDIV3_FIMC1_SHIFT (20)
186#define S5PC100_CLKDIV3_FIMC2_MASK (0xf<<24)
187#define S5PC100_CLKDIV3_FIMC2_SHIFT (24)
188#define S5PC100_CLKDIV3_HDMI_MASK (0xf<<28)
189#define S5PC100_CLKDIV3_HDMI_SHIFT (28)
190
191/* CLKDIV4 */
192#define S5PC100_CLKDIV4_PWI_MASK (0x7<<0)
193#define S5PC100_CLKDIV4_PWI_SHIFT (0)
194#define S5PC100_CLKDIV4_HCLKD2_MASK (0x7<<4)
195#define S5PC100_CLKDIV4_HCLKD2_SHIFT (4)
196#define S5PC100_CLKDIV4_I2SD2_MASK (0xf<<8)
197#define S5PC100_CLKDIV4_I2SD2_SHIFT (8)
198#define S5PC100_CLKDIV4_AUDIO0_MASK (0xf<<12)
199#define S5PC100_CLKDIV4_AUDIO0_SHIFT (12)
200#define S5PC100_CLKDIV4_AUDIO1_MASK (0xf<<16)
201#define S5PC100_CLKDIV4_AUDIO1_SHIFT (16)
202#define S5PC100_CLKDIV4_AUDIO2_MASK (0xf<<20)
203#define S5PC100_CLKDIV4_AUDIO2_SHIFT (20)
204
205
206/* HCLKD0/PCLKD0 Clock Gate 0 Registers */
207#define S5PC100_CLKGATE_D00_INTC (1<<0)
208#define S5PC100_CLKGATE_D00_TZIC (1<<1)
209#define S5PC100_CLKGATE_D00_CFCON (1<<2)
210#define S5PC100_CLKGATE_D00_MDMA (1<<3)
211#define S5PC100_CLKGATE_D00_G2D (1<<4)
212#define S5PC100_CLKGATE_D00_SECSS (1<<5)
213#define S5PC100_CLKGATE_D00_CSSYS (1<<6)
214
215/* HCLKD0/PCLKD0 Clock Gate 1 Registers */
216#define S5PC100_CLKGATE_D01_DMC (1<<0)
217#define S5PC100_CLKGATE_D01_SROMC (1<<1)
218#define S5PC100_CLKGATE_D01_ONENAND (1<<2)
219#define S5PC100_CLKGATE_D01_NFCON (1<<3)
220#define S5PC100_CLKGATE_D01_INTMEM (1<<4)
221#define S5PC100_CLKGATE_D01_EBI (1<<5)
222
223/* PCLKD0 Clock Gate 2 Registers */
224#define S5PC100_CLKGATE_D02_SECKEY (1<<1)
225#define S5PC100_CLKGATE_D02_SDM (1<<2)
226
227/* HCLKD1/PCLKD1 Clock Gate 0 Registers */
228#define S5PC100_CLKGATE_D10_PDMA0 (1<<0)
229#define S5PC100_CLKGATE_D10_PDMA1 (1<<1)
230#define S5PC100_CLKGATE_D10_USBHOST (1<<2)
231#define S5PC100_CLKGATE_D10_USBOTG (1<<3)
232#define S5PC100_CLKGATE_D10_MODEMIF (1<<4)
233#define S5PC100_CLKGATE_D10_HSMMC0 (1<<5)
234#define S5PC100_CLKGATE_D10_HSMMC1 (1<<6)
235#define S5PC100_CLKGATE_D10_HSMMC2 (1<<7)
236
237/* HCLKD1/PCLKD1 Clock Gate 1 Registers */
238#define S5PC100_CLKGATE_D11_LCD (1<<0)
239#define S5PC100_CLKGATE_D11_ROTATOR (1<<1)
240#define S5PC100_CLKGATE_D11_FIMC0 (1<<2)
241#define S5PC100_CLKGATE_D11_FIMC1 (1<<3)
242#define S5PC100_CLKGATE_D11_FIMC2 (1<<4)
243#define S5PC100_CLKGATE_D11_JPEG (1<<5)
244#define S5PC100_CLKGATE_D11_DSI (1<<6)
245#define S5PC100_CLKGATE_D11_CSI (1<<7)
246#define S5PC100_CLKGATE_D11_G3D (1<<8)
247
248/* HCLKD1/PCLKD1 Clock Gate 2 Registers */
249#define S5PC100_CLKGATE_D12_TV (1<<0)
250#define S5PC100_CLKGATE_D12_VP (1<<1)
251#define S5PC100_CLKGATE_D12_MIXER (1<<2)
252#define S5PC100_CLKGATE_D12_HDMI (1<<3)
253#define S5PC100_CLKGATE_D12_MFC (1<<4)
254
255/* HCLKD1/PCLKD1 Clock Gate 3 Registers */
256#define S5PC100_CLKGATE_D13_CHIPID (1<<0)
257#define S5PC100_CLKGATE_D13_GPIO (1<<1)
258#define S5PC100_CLKGATE_D13_APC (1<<2)
259#define S5PC100_CLKGATE_D13_IEC (1<<3)
260#define S5PC100_CLKGATE_D13_PWM (1<<6)
261#define S5PC100_CLKGATE_D13_SYSTIMER (1<<7)
262#define S5PC100_CLKGATE_D13_WDT (1<<8)
263#define S5PC100_CLKGATE_D13_RTC (1<<9)
264
265/* HCLKD1/PCLKD1 Clock Gate 4 Registers */
266#define S5PC100_CLKGATE_D14_UART0 (1<<0)
267#define S5PC100_CLKGATE_D14_UART1 (1<<1)
268#define S5PC100_CLKGATE_D14_UART2 (1<<2)
269#define S5PC100_CLKGATE_D14_UART3 (1<<3)
270#define S5PC100_CLKGATE_D14_IIC (1<<4)
271#define S5PC100_CLKGATE_D14_HDMI_IIC (1<<5)
272#define S5PC100_CLKGATE_D14_SPI0 (1<<6)
273#define S5PC100_CLKGATE_D14_SPI1 (1<<7)
274#define S5PC100_CLKGATE_D14_SPI2 (1<<8)
275#define S5PC100_CLKGATE_D14_IRDA (1<<9)
276#define S5PC100_CLKGATE_D14_CCAN0 (1<<10)
277#define S5PC100_CLKGATE_D14_CCAN1 (1<<11)
278#define S5PC100_CLKGATE_D14_HSITX (1<<12)
279#define S5PC100_CLKGATE_D14_HSIRX (1<<13)
280
281/* HCLKD1/PCLKD1 Clock Gate 5 Registers */
282#define S5PC100_CLKGATE_D15_IIS0 (1<<0)
283#define S5PC100_CLKGATE_D15_IIS1 (1<<1)
284#define S5PC100_CLKGATE_D15_IIS2 (1<<2)
285#define S5PC100_CLKGATE_D15_AC97 (1<<3)
286#define S5PC100_CLKGATE_D15_PCM0 (1<<4)
287#define S5PC100_CLKGATE_D15_PCM1 (1<<5)
288#define S5PC100_CLKGATE_D15_SPDIF (1<<6)
289#define S5PC100_CLKGATE_D15_TSADC (1<<7)
290#define S5PC100_CLKGATE_D15_KEYIF (1<<8)
291#define S5PC100_CLKGATE_D15_CG (1<<9)
292
293/* HCLKD2 Clock Gate 0 Registers */
294#define S5PC100_CLKGATE_D20_HCLKD2 (1<<0)
295#define S5PC100_CLKGATE_D20_I2SD2 (1<<1)
296
297/* Special Clock Gate 0 Registers */
298#define S5PC1XX_CLKGATE_SCLK0_HPM (1<<0)
299#define S5PC1XX_CLKGATE_SCLK0_PWI (1<<1)
300#define S5PC100_CLKGATE_SCLK0_ONENAND (1<<2)
301#define S5PC100_CLKGATE_SCLK0_UART (1<<3)
302#define S5PC100_CLKGATE_SCLK0_SPI0 (1<<4)
303#define S5PC100_CLKGATE_SCLK0_SPI1 (1<<5)
304#define S5PC100_CLKGATE_SCLK0_SPI2 (1<<6)
305#define S5PC100_CLKGATE_SCLK0_SPI0_48 (1<<7)
306#define S5PC100_CLKGATE_SCLK0_SPI1_48 (1<<8)
307#define S5PC100_CLKGATE_SCLK0_SPI2_48 (1<<9)
308#define S5PC100_CLKGATE_SCLK0_IRDA (1<<10)
309#define S5PC100_CLKGATE_SCLK0_USBHOST (1<<11)
310#define S5PC100_CLKGATE_SCLK0_MMC0 (1<<12)
311#define S5PC100_CLKGATE_SCLK0_MMC1 (1<<13)
312#define S5PC100_CLKGATE_SCLK0_MMC2 (1<<14)
313#define S5PC100_CLKGATE_SCLK0_MMC0_48 (1<<15)
314#define S5PC100_CLKGATE_SCLK0_MMC1_48 (1<<16)
315#define S5PC100_CLKGATE_SCLK0_MMC2_48 (1<<17)
316
317/* Special Clock Gate 1 Registers */
318#define S5PC100_CLKGATE_SCLK1_LCD (1<<0)
319#define S5PC100_CLKGATE_SCLK1_FIMC0 (1<<1)
320#define S5PC100_CLKGATE_SCLK1_FIMC1 (1<<2)
321#define S5PC100_CLKGATE_SCLK1_FIMC2 (1<<3)
322#define S5PC100_CLKGATE_SCLK1_TV54 (1<<4)
323#define S5PC100_CLKGATE_SCLK1_VDAC54 (1<<5)
324#define S5PC100_CLKGATE_SCLK1_MIXER (1<<6)
325#define S5PC100_CLKGATE_SCLK1_HDMI (1<<7)
326#define S5PC100_CLKGATE_SCLK1_AUDIO0 (1<<8)
327#define S5PC100_CLKGATE_SCLK1_AUDIO1 (1<<9)
328#define S5PC100_CLKGATE_SCLK1_AUDIO2 (1<<10)
329#define S5PC100_CLKGATE_SCLK1_SPDIF (1<<11)
330#define S5PC100_CLKGATE_SCLK1_CAM (1<<12)
331
332/* register for power management */
333#define S5PC100_PWR_CFG S5PC1XX_CLKREG(0x8000)
334#define S5PC100_EINT_WAKEUP_MASK S5PC1XX_CLKREG(0x8004)
335#define S5PC100_NORMAL_CFG S5PC1XX_CLKREG(0x8010)
336#define S5PC100_STOP_CFG S5PC1XX_CLKREG(0x8014)
337#define S5PC100_SLEEP_CFG S5PC1XX_CLKREG(0x8018)
338#define S5PC100_STOP_MEM_CFG S5PC1XX_CLKREG(0x801C)
339#define S5PC100_OSC_FREQ S5PC1XX_CLKREG(0x8100)
340#define S5PC100_OSC_STABLE S5PC1XX_CLKREG(0x8104)
341#define S5PC100_PWR_STABLE S5PC1XX_CLKREG(0x8108)
342#define S5PC100_MTC_STABLE S5PC1XX_CLKREG(0x8110)
343#define S5PC100_CLAMP_STABLE S5PC1XX_CLKREG(0x8114)
344#define S5PC100_OTHERS S5PC1XX_CLKREG(0x8200)
345#define S5PC100_RST_STAT S5PC1XX_CLKREG(0x8300)
346#define S5PC100_WAKEUP_STAT S5PC1XX_CLKREG(0x8304)
347#define S5PC100_BLK_PWR_STAT S5PC1XX_CLKREG(0x8308)
348#define S5PC100_INFORM0 S5PC1XX_CLKREG(0x8400)
349#define S5PC100_INFORM1 S5PC1XX_CLKREG(0x8404)
350#define S5PC100_INFORM2 S5PC1XX_CLKREG(0x8408)
351#define S5PC100_INFORM3 S5PC1XX_CLKREG(0x840C)
352#define S5PC100_INFORM4 S5PC1XX_CLKREG(0x8410)
353#define S5PC100_INFORM5 S5PC1XX_CLKREG(0x8414)
354#define S5PC100_INFORM6 S5PC1XX_CLKREG(0x8418)
355#define S5PC100_INFORM7 S5PC1XX_CLKREG(0x841C)
356#define S5PC100_DCGIDX_MAP0 S5PC1XX_CLKREG(0x8500)
357#define S5PC100_DCGIDX_MAP1 S5PC1XX_CLKREG(0x8504)
358#define S5PC100_DCGIDX_MAP2 S5PC1XX_CLKREG(0x8508)
359#define S5PC100_DCGPERF_MAP0 S5PC1XX_CLKREG(0x850C)
360#define S5PC100_DCGPERF_MAP1 S5PC1XX_CLKREG(0x8510)
361#define S5PC100_DVCIDX_MAP S5PC1XX_CLKREG(0x8514)
362#define S5PC100_FREQ_CPU S5PC1XX_CLKREG(0x8518)
363#define S5PC100_FREQ_DPM S5PC1XX_CLKREG(0x851C)
364#define S5PC100_DVSEMCLK_EN S5PC1XX_CLKREG(0x8520)
365#define S5PC100_APLL_CON_L8 S5PC1XX_CLKREG(0x8600)
366#define S5PC100_APLL_CON_L7 S5PC1XX_CLKREG(0x8604)
367#define S5PC100_APLL_CON_L6 S5PC1XX_CLKREG(0x8608)
368#define S5PC100_APLL_CON_L5 S5PC1XX_CLKREG(0x860C)
369#define S5PC100_APLL_CON_L4 S5PC1XX_CLKREG(0x8610)
370#define S5PC100_APLL_CON_L3 S5PC1XX_CLKREG(0x8614)
371#define S5PC100_APLL_CON_L2 S5PC1XX_CLKREG(0x8618)
372#define S5PC100_APLL_CON_L1 S5PC1XX_CLKREG(0x861C)
373#define S5PC100_IEM_CONTROL S5PC1XX_CLKREG(0x8620)
374#define S5PC100_CLKDIV_IEM_L8 S5PC1XX_CLKREG(0x8700)
375#define S5PC100_CLKDIV_IEM_L7 S5PC1XX_CLKREG(0x8704)
376#define S5PC100_CLKDIV_IEM_L6 S5PC1XX_CLKREG(0x8708)
377#define S5PC100_CLKDIV_IEM_L5 S5PC1XX_CLKREG(0x870C)
378#define S5PC100_CLKDIV_IEM_L4 S5PC1XX_CLKREG(0x8710)
379#define S5PC100_CLKDIV_IEM_L3 S5PC1XX_CLKREG(0x8714)
380#define S5PC100_CLKDIV_IEM_L2 S5PC1XX_CLKREG(0x8718)
381#define S5PC100_CLKDIV_IEM_L1 S5PC1XX_CLKREG(0x871C)
382#define S5PC100_IEM_HPMCLK_DIV S5PC1XX_CLKREG(0x8724)
383
384#define S5PC100_SWRESET S5PC1XX_CLKREG(0x100000)
385#define S5PC100_OND_SWRESET S5PC1XX_CLKREG(0x100008)
386#define S5PC100_GEN_CTRL S5PC1XX_CLKREG(0x100100)
387#define S5PC100_GEN_STATUS S5PC1XX_CLKREG(0x100104)
388#define S5PC100_MEM_SYS_CFG S5PC1XX_CLKREG(0x100200)
389#define S5PC100_CAM_MUX_SEL S5PC1XX_CLKREG(0x100300)
390#define S5PC100_MIXER_OUT_SEL S5PC1XX_CLKREG(0x100304)
391#define S5PC100_LPMP_MODE_SEL S5PC1XX_CLKREG(0x100308)
392#define S5PC100_MIPI_PHY_CON0 S5PC1XX_CLKREG(0x100400)
393#define S5PC100_MIPI_PHY_CON1 S5PC1XX_CLKREG(0x100414)
394#define S5PC100_HDMI_PHY_CON0 S5PC1XX_CLKREG(0x100420)
395
396#define S5PC100_CFG_WFI_CLEAN (~(3<<5))
397#define S5PC100_CFG_WFI_IDLE (1<<5)
398#define S5PC100_CFG_WFI_STOP (2<<5)
399#define S5PC100_CFG_WFI_SLEEP (3<<5)
400
401#define S5PC100_OTHER_SYS_INT 24
402#define S5PC100_OTHER_STA_TYPE 23
403#define STA_TYPE_EXPON 0
404#define STA_TYPE_SFR 1
405
406#define S5PC100_PWR_STA_EXP_SCALE 0
407#define S5PC100_PWR_STA_CNT 4
408
409#define S5PC100_PWR_STABLE_COUNT 85500
410
411#define S5PC100_SLEEP_CFG_OSC_EN 0
412
413/* OTHERS Resgister */
414#define S5PC100_OTHERS_USB_SIG_MASK (1 << 16)
415#define S5PC100_OTHERS_MIPI_DPHY_EN (1 << 28)
416
417/* MIPI D-PHY Control Register 0 */
418#define S5PC100_MIPI_PHY_CON0_M_RESETN (1 << 1)
419#define S5PC100_MIPI_PHY_CON0_S_RESETN (1 << 0)
420
421#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
new file mode 100644
index 000000000000..45e275131665
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
@@ -0,0 +1,65 @@
1/* arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Header file for s5pc100 cpu support
7 *
8 * Based on plat-s3c64xx/include/plat/s3c6400.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15/* Common init code for S5PC100 related SoCs */
16extern int s5pc100_init(void);
17extern void s5pc100_map_io(void);
18extern void s5pc100_init_clocks(int xtal);
19extern int s5pc100_register_baseclocks(unsigned long xtal);
20extern void s5pc100_init_irq(void);
21extern void s5pc100_init_io(struct map_desc *mach_desc, int size);
22extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
23extern void s5pc100_register_clocks(void);
24extern void s5pc100_setup_clocks(void);
25extern struct sysdev_class s5pc100_sysclass;
26
27#define s5pc100_init_uarts s5pc100_common_init_uarts
28
29/* Some day, belows will be moved to plat-s5pc/include/plat/cpu.h */
30extern void s5pc1xx_init_irq(u32 *vic_valid, int num);
31extern void s5pc1xx_init_io(struct map_desc *mach_desc, int size);
32
33/* Some day, belows will be moved to plat-s5pc/include/plat/clock.h */
34extern struct clk clk_hpll;
35extern struct clk clk_hd0;
36extern struct clk clk_pd0;
37extern struct clk clk_54m;
38extern struct clk clk_dout_mpll2;
39extern void s5pc1xx_register_clocks(void);
40extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable);
41extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable);
42
43/* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */
44extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[];
45extern struct platform_device s3c_device_g2d;
46extern struct platform_device s3c_device_g3d;
47extern struct platform_device s3c_device_vpp;
48extern struct platform_device s3c_device_tvenc;
49extern struct platform_device s3c_device_tvscaler;
50extern struct platform_device s3c_device_rotator;
51extern struct platform_device s3c_device_jpeg;
52extern struct platform_device s3c_device_onenand;
53extern struct platform_device s3c_device_usb_otghcd;
54extern struct platform_device s3c_device_keypad;
55extern struct platform_device s3c_device_ts;
56extern struct platform_device s3c_device_g3d;
57extern struct platform_device s3c_device_smc911x;
58extern struct platform_device s3c_device_fimc0;
59extern struct platform_device s3c_device_fimc1;
60extern struct platform_device s3c_device_mfc;
61extern struct platform_device s3c_device_ac97;
62extern struct platform_device s3c_device_fimc0;
63extern struct platform_device s3c_device_fimc1;
64extern struct platform_device s3c_device_fimc2;
65
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
new file mode 100644
index 000000000000..80d6dd942cb8
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq.c
@@ -0,0 +1,259 @@
1/* arch/arm/plat-s5pc1xx/irq.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX - Interrupt handling
7 *
8 * Based on plat-s3c64xx/irq.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/io.h>
19
20#include <asm/hardware/vic.h>
21
22#include <mach/map.h>
23#include <plat/regs-timer.h>
24#include <plat/cpu.h>
25
26/* Timer interrupt handling */
27
28static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
29{
30 generic_handle_irq(sub_irq);
31}
32
33static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
34{
35 s3c_irq_demux_timer(irq, IRQ_TIMER0);
36}
37
38static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
39{
40 s3c_irq_demux_timer(irq, IRQ_TIMER1);
41}
42
43static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
44{
45 s3c_irq_demux_timer(irq, IRQ_TIMER2);
46}
47
48static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
49{
50 s3c_irq_demux_timer(irq, IRQ_TIMER3);
51}
52
53static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
54{
55 s3c_irq_demux_timer(irq, IRQ_TIMER4);
56}
57
58/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
59
60static void s3c_irq_timer_mask(unsigned int irq)
61{
62 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
63
64 reg &= 0x1f; /* mask out pending interrupts */
65 reg &= ~(1 << (irq - IRQ_TIMER0));
66 __raw_writel(reg, S3C64XX_TINT_CSTAT);
67}
68
69static void s3c_irq_timer_unmask(unsigned int irq)
70{
71 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
72
73 reg &= 0x1f; /* mask out pending interrupts */
74 reg |= 1 << (irq - IRQ_TIMER0);
75 __raw_writel(reg, S3C64XX_TINT_CSTAT);
76}
77
78static void s3c_irq_timer_ack(unsigned int irq)
79{
80 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
81
82 reg &= 0x1f;
83 reg |= (1 << 5) << (irq - IRQ_TIMER0);
84 __raw_writel(reg, S3C64XX_TINT_CSTAT);
85}
86
87static struct irq_chip s3c_irq_timer = {
88 .name = "s3c-timer",
89 .mask = s3c_irq_timer_mask,
90 .unmask = s3c_irq_timer_unmask,
91 .ack = s3c_irq_timer_ack,
92};
93
94struct uart_irq {
95 void __iomem *regs;
96 unsigned int base_irq;
97 unsigned int parent_irq;
98};
99
100/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
101 * are consecutive when looking up the interrupt in the demux routines.
102 */
103static struct uart_irq uart_irqs[] = {
104 [0] = {
105 .regs = (void *)S3C_VA_UART0,
106 .base_irq = IRQ_S3CUART_BASE0,
107 .parent_irq = IRQ_UART0,
108 },
109 [1] = {
110 .regs = (void *)S3C_VA_UART1,
111 .base_irq = IRQ_S3CUART_BASE1,
112 .parent_irq = IRQ_UART1,
113 },
114 [2] = {
115 .regs = (void *)S3C_VA_UART2,
116 .base_irq = IRQ_S3CUART_BASE2,
117 .parent_irq = IRQ_UART2,
118 },
119 [3] = {
120 .regs = (void *)S3C_VA_UART3,
121 .base_irq = IRQ_S3CUART_BASE3,
122 .parent_irq = IRQ_UART3,
123 },
124};
125
126static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
127{
128 struct uart_irq *uirq = get_irq_chip_data(irq);
129 return uirq->regs;
130}
131
132static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
133{
134 return irq & 3;
135}
136
137/* UART interrupt registers, not worth adding to seperate include header */
138#define S3C64XX_UINTP 0x30
139#define S3C64XX_UINTSP 0x34
140#define S3C64XX_UINTM 0x38
141
142static void s3c_irq_uart_mask(unsigned int irq)
143{
144 void __iomem *regs = s3c_irq_uart_base(irq);
145 unsigned int bit = s3c_irq_uart_bit(irq);
146 u32 reg;
147
148 reg = __raw_readl(regs + S3C64XX_UINTM);
149 reg |= (1 << bit);
150 __raw_writel(reg, regs + S3C64XX_UINTM);
151}
152
153static void s3c_irq_uart_maskack(unsigned int irq)
154{
155 void __iomem *regs = s3c_irq_uart_base(irq);
156 unsigned int bit = s3c_irq_uart_bit(irq);
157 u32 reg;
158
159 reg = __raw_readl(regs + S3C64XX_UINTM);
160 reg |= (1 << bit);
161 __raw_writel(reg, regs + S3C64XX_UINTM);
162 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
163}
164
165static void s3c_irq_uart_unmask(unsigned int irq)
166{
167 void __iomem *regs = s3c_irq_uart_base(irq);
168 unsigned int bit = s3c_irq_uart_bit(irq);
169 u32 reg;
170
171 reg = __raw_readl(regs + S3C64XX_UINTM);
172 reg &= ~(1 << bit);
173 __raw_writel(reg, regs + S3C64XX_UINTM);
174}
175
176static void s3c_irq_uart_ack(unsigned int irq)
177{
178 void __iomem *regs = s3c_irq_uart_base(irq);
179 unsigned int bit = s3c_irq_uart_bit(irq);
180
181 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
182}
183
184static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
185{
186 struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
187 u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
188 int base = uirq->base_irq;
189
190 if (pend & (1 << 0))
191 generic_handle_irq(base);
192 if (pend & (1 << 1))
193 generic_handle_irq(base + 1);
194 if (pend & (1 << 2))
195 generic_handle_irq(base + 2);
196 if (pend & (1 << 3))
197 generic_handle_irq(base + 3);
198}
199
200static struct irq_chip s3c_irq_uart = {
201 .name = "s3c-uart",
202 .mask = s3c_irq_uart_mask,
203 .unmask = s3c_irq_uart_unmask,
204 .mask_ack = s3c_irq_uart_maskack,
205 .ack = s3c_irq_uart_ack,
206};
207
208static void __init s5pc1xx_uart_irq(struct uart_irq *uirq)
209{
210 void __iomem *reg_base = uirq->regs;
211 unsigned int irq;
212 int offs;
213
214 /* mask all interrupts at the start. */
215 __raw_writel(0xf, reg_base + S3C64XX_UINTM);
216
217 for (offs = 0; offs < 3; offs++) {
218 irq = uirq->base_irq + offs;
219
220 set_irq_chip(irq, &s3c_irq_uart);
221 set_irq_chip_data(irq, uirq);
222 set_irq_handler(irq, handle_level_irq);
223 set_irq_flags(irq, IRQF_VALID);
224 }
225
226 set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
227}
228
229void __init s5pc1xx_init_irq(u32 *vic_valid, int num)
230{
231 int i;
232 int uart, irq;
233
234 printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
235
236 /* initialise the pair of VICs */
237 for (i = 0; i < num; i++)
238 vic_init((void *)S5PC1XX_VA_VIC(i), S3C_IRQ(i * S3C_IRQ_OFFSET),
239 vic_valid[i], 0);
240
241 /* add the timer sub-irqs */
242
243 set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0);
244 set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1);
245 set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2);
246 set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3);
247 set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4);
248
249 for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
250 set_irq_chip(irq, &s3c_irq_timer);
251 set_irq_handler(irq, handle_level_irq);
252 set_irq_flags(irq, IRQF_VALID);
253 }
254
255 for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
256 s5pc1xx_uart_irq(&uart_irqs[uart]);
257}
258
259
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
new file mode 100644
index 000000000000..6b24035172fa
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -0,0 +1,1139 @@
1/* linux/arch/arm/plat-s5pc1xx/s5pc100-clock.c
2 *
3 * Copyright 2009 Samsung Electronics, Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 based common clock support
7 *
8 * Based on plat-s3c64xx/s3c6400-clock.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/err.h>
21#include <linux/clk.h>
22#include <linux/sysdev.h>
23#include <linux/io.h>
24
25#include <mach/hardware.h>
26#include <mach/map.h>
27
28#include <plat/cpu-freq.h>
29
30#include <plat/regs-clock.h>
31#include <plat/clock.h>
32#include <plat/cpu.h>
33#include <plat/pll.h>
34#include <plat/devs.h>
35#include <plat/s5pc100.h>
36
37/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
38 * ext_xtal_mux for want of an actual name from the manual.
39*/
40
41static struct clk clk_ext_xtal_mux = {
42 .name = "ext_xtal",
43 .id = -1,
44};
45
46#define clk_fin_apll clk_ext_xtal_mux
47#define clk_fin_mpll clk_ext_xtal_mux
48#define clk_fin_epll clk_ext_xtal_mux
49#define clk_fin_hpll clk_ext_xtal_mux
50
51#define clk_fout_mpll clk_mpll
52
53struct clk_sources {
54 unsigned int nr_sources;
55 struct clk **sources;
56};
57
58struct clksrc_clk {
59 struct clk clk;
60 unsigned int mask;
61 unsigned int shift;
62
63 struct clk_sources *sources;
64
65 unsigned int divider_shift;
66 void __iomem *reg_divider;
67 void __iomem *reg_source;
68};
69
70static int clk_default_setrate(struct clk *clk, unsigned long rate)
71{
72 clk->rate = rate;
73 return 1;
74}
75
76struct clk clk_27m = {
77 .name = "clk_27m",
78 .id = -1,
79 .rate = 27000000,
80};
81
82static int clk_48m_ctrl(struct clk *clk, int enable)
83{
84 unsigned long flags;
85 u32 val;
86
87 /* can't rely on clock lock, this register has other usages */
88 local_irq_save(flags);
89
90 val = __raw_readl(S5PC1XX_CLK_SRC1);
91 if (enable)
92 val |= S5PC100_CLKSRC1_CLK48M_MASK;
93 else
94 val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
95
96 __raw_writel(val, S5PC1XX_CLK_SRC1);
97 local_irq_restore(flags);
98
99 return 0;
100}
101
102struct clk clk_48m = {
103 .name = "clk_48m",
104 .id = -1,
105 .rate = 48000000,
106 .enable = clk_48m_ctrl,
107};
108
109struct clk clk_54m = {
110 .name = "clk_54m",
111 .id = -1,
112 .rate = 54000000,
113};
114
115struct clk clk_hpll = {
116 .name = "hpll",
117 .id = -1,
118};
119
120struct clk clk_hd0 = {
121 .name = "hclkd0",
122 .id = -1,
123 .rate = 0,
124 .parent = NULL,
125 .ctrlbit = 0,
126 .set_rate = clk_default_setrate,
127};
128
129struct clk clk_pd0 = {
130 .name = "pclkd0",
131 .id = -1,
132 .rate = 0,
133 .parent = NULL,
134 .ctrlbit = 0,
135 .set_rate = clk_default_setrate,
136};
137
138static int s5pc1xx_clk_gate(void __iomem *reg,
139 struct clk *clk,
140 int enable)
141{
142 unsigned int ctrlbit = clk->ctrlbit;
143 u32 con;
144
145 con = __raw_readl(reg);
146
147 if (enable)
148 con |= ctrlbit;
149 else
150 con &= ~ctrlbit;
151
152 __raw_writel(con, reg);
153 return 0;
154}
155
156static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
157{
158 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
159}
160
161static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
162{
163 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
164}
165
166static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
167{
168 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
169}
170
171static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
172{
173 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
174}
175
176static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
177{
178 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
179}
180
181static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
182{
183 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
184}
185
186static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
187{
188 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
189}
190
191static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
192{
193 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
194}
195
196static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
197{
198 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
199}
200
201static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
202{
203 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
204}
205
206int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
207{
208 return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
209}
210
211int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
212{
213 return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
214}
215
216static struct clk init_clocks_disable[] = {
217 {
218 .name = "dsi",
219 .id = -1,
220 .parent = &clk_p,
221 .enable = s5pc1xx_clk_d11_ctrl,
222 .ctrlbit = S5PC100_CLKGATE_D11_DSI,
223 }, {
224 .name = "csi",
225 .id = -1,
226 .parent = &clk_h,
227 .enable = s5pc1xx_clk_d11_ctrl,
228 .ctrlbit = S5PC100_CLKGATE_D11_CSI,
229 }, {
230 .name = "ccan0",
231 .id = 0,
232 .parent = &clk_p,
233 .enable = s5pc1xx_clk_d14_ctrl,
234 .ctrlbit = S5PC100_CLKGATE_D14_CCAN0,
235 }, {
236 .name = "ccan1",
237 .id = 1,
238 .parent = &clk_p,
239 .enable = s5pc1xx_clk_d14_ctrl,
240 .ctrlbit = S5PC100_CLKGATE_D14_CCAN1,
241 }, {
242 .name = "keypad",
243 .id = -1,
244 .parent = &clk_p,
245 .enable = s5pc1xx_clk_d15_ctrl,
246 .ctrlbit = S5PC100_CLKGATE_D15_KEYIF,
247 }, {
248 .name = "hclkd2",
249 .id = -1,
250 .parent = NULL,
251 .enable = s5pc1xx_clk_d20_ctrl,
252 .ctrlbit = S5PC100_CLKGATE_D20_HCLKD2,
253 }, {
254 .name = "iis-d2",
255 .id = -1,
256 .parent = NULL,
257 .enable = s5pc1xx_clk_d20_ctrl,
258 .ctrlbit = S5PC100_CLKGATE_D20_I2SD2,
259 }, {
260 .name = "otg",
261 .id = -1,
262 .parent = &clk_h,
263 .enable = s5pc1xx_clk_d10_ctrl,
264 .ctrlbit = S5PC100_CLKGATE_D10_USBOTG,
265 },
266};
267
268static struct clk init_clocks[] = {
269 /* System1 (D0_0) devices */
270 {
271 .name = "intc",
272 .id = -1,
273 .parent = &clk_hd0,
274 .enable = s5pc1xx_clk_d00_ctrl,
275 .ctrlbit = S5PC100_CLKGATE_D00_INTC,
276 }, {
277 .name = "tzic",
278 .id = -1,
279 .parent = &clk_hd0,
280 .enable = s5pc1xx_clk_d00_ctrl,
281 .ctrlbit = S5PC100_CLKGATE_D00_TZIC,
282 }, {
283 .name = "cf-ata",
284 .id = -1,
285 .parent = &clk_hd0,
286 .enable = s5pc1xx_clk_d00_ctrl,
287 .ctrlbit = S5PC100_CLKGATE_D00_CFCON,
288 }, {
289 .name = "mdma",
290 .id = -1,
291 .parent = &clk_hd0,
292 .enable = s5pc1xx_clk_d00_ctrl,
293 .ctrlbit = S5PC100_CLKGATE_D00_MDMA,
294 }, {
295 .name = "g2d",
296 .id = -1,
297 .parent = &clk_hd0,
298 .enable = s5pc1xx_clk_d00_ctrl,
299 .ctrlbit = S5PC100_CLKGATE_D00_G2D,
300 }, {
301 .name = "secss",
302 .id = -1,
303 .parent = &clk_hd0,
304 .enable = s5pc1xx_clk_d00_ctrl,
305 .ctrlbit = S5PC100_CLKGATE_D00_SECSS,
306 }, {
307 .name = "cssys",
308 .id = -1,
309 .parent = &clk_hd0,
310 .enable = s5pc1xx_clk_d00_ctrl,
311 .ctrlbit = S5PC100_CLKGATE_D00_CSSYS,
312 },
313
314 /* Memory (D0_1) devices */
315 {
316 .name = "dmc",
317 .id = -1,
318 .parent = &clk_hd0,
319 .enable = s5pc1xx_clk_d01_ctrl,
320 .ctrlbit = S5PC100_CLKGATE_D01_DMC,
321 }, {
322 .name = "sromc",
323 .id = -1,
324 .parent = &clk_hd0,
325 .enable = s5pc1xx_clk_d01_ctrl,
326 .ctrlbit = S5PC100_CLKGATE_D01_SROMC,
327 }, {
328 .name = "onenand",
329 .id = -1,
330 .parent = &clk_hd0,
331 .enable = s5pc1xx_clk_d01_ctrl,
332 .ctrlbit = S5PC100_CLKGATE_D01_ONENAND,
333 }, {
334 .name = "nand",
335 .id = -1,
336 .parent = &clk_hd0,
337 .enable = s5pc1xx_clk_d01_ctrl,
338 .ctrlbit = S5PC100_CLKGATE_D01_NFCON,
339 }, {
340 .name = "intmem",
341 .id = -1,
342 .parent = &clk_hd0,
343 .enable = s5pc1xx_clk_d01_ctrl,
344 .ctrlbit = S5PC100_CLKGATE_D01_INTMEM,
345 }, {
346 .name = "ebi",
347 .id = -1,
348 .parent = &clk_hd0,
349 .enable = s5pc1xx_clk_d01_ctrl,
350 .ctrlbit = S5PC100_CLKGATE_D01_EBI,
351 },
352
353 /* System2 (D0_2) devices */
354 {
355 .name = "seckey",
356 .id = -1,
357 .parent = &clk_pd0,
358 .enable = s5pc1xx_clk_d02_ctrl,
359 .ctrlbit = S5PC100_CLKGATE_D02_SECKEY,
360 }, {
361 .name = "sdm",
362 .id = -1,
363 .parent = &clk_hd0,
364 .enable = s5pc1xx_clk_d02_ctrl,
365 .ctrlbit = S5PC100_CLKGATE_D02_SDM,
366 },
367
368 /* File (D1_0) devices */
369 {
370 .name = "pdma0",
371 .id = -1,
372 .parent = &clk_h,
373 .enable = s5pc1xx_clk_d10_ctrl,
374 .ctrlbit = S5PC100_CLKGATE_D10_PDMA0,
375 }, {
376 .name = "pdma1",
377 .id = -1,
378 .parent = &clk_h,
379 .enable = s5pc1xx_clk_d10_ctrl,
380 .ctrlbit = S5PC100_CLKGATE_D10_PDMA1,
381 }, {
382 .name = "usb-host",
383 .id = -1,
384 .parent = &clk_h,
385 .enable = s5pc1xx_clk_d10_ctrl,
386 .ctrlbit = S5PC100_CLKGATE_D10_USBHOST,
387 }, {
388 .name = "modem",
389 .id = -1,
390 .parent = &clk_h,
391 .enable = s5pc1xx_clk_d10_ctrl,
392 .ctrlbit = S5PC100_CLKGATE_D10_MODEMIF,
393 }, {
394 .name = "hsmmc",
395 .id = 0,
396 .parent = &clk_h,
397 .enable = s5pc1xx_clk_d10_ctrl,
398 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC0,
399 }, {
400 .name = "hsmmc",
401 .id = 1,
402 .parent = &clk_h,
403 .enable = s5pc1xx_clk_d10_ctrl,
404 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC1,
405 }, {
406 .name = "hsmmc",
407 .id = 2,
408 .parent = &clk_h,
409 .enable = s5pc1xx_clk_d10_ctrl,
410 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC2,
411 },
412
413 /* Multimedia1 (D1_1) devices */
414 {
415 .name = "lcd",
416 .id = -1,
417 .parent = &clk_h,
418 .enable = s5pc1xx_clk_d11_ctrl,
419 .ctrlbit = S5PC100_CLKGATE_D11_LCD,
420 }, {
421 .name = "rotator",
422 .id = -1,
423 .parent = &clk_h,
424 .enable = s5pc1xx_clk_d11_ctrl,
425 .ctrlbit = S5PC100_CLKGATE_D11_ROTATOR,
426 }, {
427 .name = "fimc",
428 .id = 0,
429 .parent = &clk_h,
430 .enable = s5pc1xx_clk_d11_ctrl,
431 .ctrlbit = S5PC100_CLKGATE_D11_FIMC0,
432 }, {
433 .name = "fimc",
434 .id = 1,
435 .parent = &clk_h,
436 .enable = s5pc1xx_clk_d11_ctrl,
437 .ctrlbit = S5PC100_CLKGATE_D11_FIMC1,
438 }, {
439 .name = "fimc",
440 .id = 2,
441 .parent = &clk_h,
442 .enable = s5pc1xx_clk_d11_ctrl,
443 .ctrlbit = S5PC100_CLKGATE_D11_FIMC2,
444 }, {
445 .name = "jpeg",
446 .id = -1,
447 .parent = &clk_h,
448 .enable = s5pc1xx_clk_d11_ctrl,
449 .ctrlbit = S5PC100_CLKGATE_D11_JPEG,
450 }, {
451 .name = "g3d",
452 .id = -1,
453 .parent = &clk_h,
454 .enable = s5pc1xx_clk_d11_ctrl,
455 .ctrlbit = S5PC100_CLKGATE_D11_G3D,
456 },
457
458 /* Multimedia2 (D1_2) devices */
459 {
460 .name = "tv",
461 .id = -1,
462 .parent = &clk_h,
463 .enable = s5pc1xx_clk_d12_ctrl,
464 .ctrlbit = S5PC100_CLKGATE_D12_TV,
465 }, {
466 .name = "vp",
467 .id = -1,
468 .parent = &clk_h,
469 .enable = s5pc1xx_clk_d12_ctrl,
470 .ctrlbit = S5PC100_CLKGATE_D12_VP,
471 }, {
472 .name = "mixer",
473 .id = -1,
474 .parent = &clk_h,
475 .enable = s5pc1xx_clk_d12_ctrl,
476 .ctrlbit = S5PC100_CLKGATE_D12_MIXER,
477 }, {
478 .name = "hdmi",
479 .id = -1,
480 .parent = &clk_h,
481 .enable = s5pc1xx_clk_d12_ctrl,
482 .ctrlbit = S5PC100_CLKGATE_D12_HDMI,
483 }, {
484 .name = "mfc",
485 .id = -1,
486 .parent = &clk_h,
487 .enable = s5pc1xx_clk_d12_ctrl,
488 .ctrlbit = S5PC100_CLKGATE_D12_MFC,
489 },
490
491 /* System (D1_3) devices */
492 {
493 .name = "chipid",
494 .id = -1,
495 .parent = &clk_p,
496 .enable = s5pc1xx_clk_d13_ctrl,
497 .ctrlbit = S5PC100_CLKGATE_D13_CHIPID,
498 }, {
499 .name = "gpio",
500 .id = -1,
501 .parent = &clk_p,
502 .enable = s5pc1xx_clk_d13_ctrl,
503 .ctrlbit = S5PC100_CLKGATE_D13_GPIO,
504 }, {
505 .name = "apc",
506 .id = -1,
507 .parent = &clk_p,
508 .enable = s5pc1xx_clk_d13_ctrl,
509 .ctrlbit = S5PC100_CLKGATE_D13_APC,
510 }, {
511 .name = "iec",
512 .id = -1,
513 .parent = &clk_p,
514 .enable = s5pc1xx_clk_d13_ctrl,
515 .ctrlbit = S5PC100_CLKGATE_D13_IEC,
516 }, {
517 .name = "timers",
518 .id = -1,
519 .parent = &clk_p,
520 .enable = s5pc1xx_clk_d13_ctrl,
521 .ctrlbit = S5PC100_CLKGATE_D13_PWM,
522 }, {
523 .name = "systimer",
524 .id = -1,
525 .parent = &clk_p,
526 .enable = s5pc1xx_clk_d13_ctrl,
527 .ctrlbit = S5PC100_CLKGATE_D13_SYSTIMER,
528 }, {
529 .name = "watchdog",
530 .id = -1,
531 .parent = &clk_p,
532 .enable = s5pc1xx_clk_d13_ctrl,
533 .ctrlbit = S5PC100_CLKGATE_D13_WDT,
534 }, {
535 .name = "rtc",
536 .id = -1,
537 .parent = &clk_p,
538 .enable = s5pc1xx_clk_d13_ctrl,
539 .ctrlbit = S5PC100_CLKGATE_D13_RTC,
540 },
541
542 /* Connectivity (D1_4) devices */
543 {
544 .name = "uart",
545 .id = 0,
546 .parent = &clk_p,
547 .enable = s5pc1xx_clk_d14_ctrl,
548 .ctrlbit = S5PC100_CLKGATE_D14_UART0,
549 }, {
550 .name = "uart",
551 .id = 1,
552 .parent = &clk_p,
553 .enable = s5pc1xx_clk_d14_ctrl,
554 .ctrlbit = S5PC100_CLKGATE_D14_UART1,
555 }, {
556 .name = "uart",
557 .id = 2,
558 .parent = &clk_p,
559 .enable = s5pc1xx_clk_d14_ctrl,
560 .ctrlbit = S5PC100_CLKGATE_D14_UART2,
561 }, {
562 .name = "uart",
563 .id = 3,
564 .parent = &clk_p,
565 .enable = s5pc1xx_clk_d14_ctrl,
566 .ctrlbit = S5PC100_CLKGATE_D14_UART3,
567 }, {
568 .name = "i2c",
569 .id = -1,
570 .parent = &clk_p,
571 .enable = s5pc1xx_clk_d14_ctrl,
572 .ctrlbit = S5PC100_CLKGATE_D14_IIC,
573 }, {
574 .name = "hdmi-i2c",
575 .id = -1,
576 .parent = &clk_p,
577 .enable = s5pc1xx_clk_d14_ctrl,
578 .ctrlbit = S5PC100_CLKGATE_D14_HDMI_IIC,
579 }, {
580 .name = "spi",
581 .id = 0,
582 .parent = &clk_p,
583 .enable = s5pc1xx_clk_d14_ctrl,
584 .ctrlbit = S5PC100_CLKGATE_D14_SPI0,
585 }, {
586 .name = "spi",
587 .id = 1,
588 .parent = &clk_p,
589 .enable = s5pc1xx_clk_d14_ctrl,
590 .ctrlbit = S5PC100_CLKGATE_D14_SPI1,
591 }, {
592 .name = "spi",
593 .id = 2,
594 .parent = &clk_p,
595 .enable = s5pc1xx_clk_d14_ctrl,
596 .ctrlbit = S5PC100_CLKGATE_D14_SPI2,
597 }, {
598 .name = "irda",
599 .id = -1,
600 .parent = &clk_p,
601 .enable = s5pc1xx_clk_d14_ctrl,
602 .ctrlbit = S5PC100_CLKGATE_D14_IRDA,
603 }, {
604 .name = "hsitx",
605 .id = -1,
606 .parent = &clk_p,
607 .enable = s5pc1xx_clk_d14_ctrl,
608 .ctrlbit = S5PC100_CLKGATE_D14_HSITX,
609 }, {
610 .name = "hsirx",
611 .id = -1,
612 .parent = &clk_p,
613 .enable = s5pc1xx_clk_d14_ctrl,
614 .ctrlbit = S5PC100_CLKGATE_D14_HSIRX,
615 },
616
617 /* Audio (D1_5) devices */
618 {
619 .name = "iis",
620 .id = 0,
621 .parent = &clk_p,
622 .enable = s5pc1xx_clk_d15_ctrl,
623 .ctrlbit = S5PC100_CLKGATE_D15_IIS0,
624 }, {
625 .name = "iis",
626 .id = 1,
627 .parent = &clk_p,
628 .enable = s5pc1xx_clk_d15_ctrl,
629 .ctrlbit = S5PC100_CLKGATE_D15_IIS1,
630 }, {
631 .name = "iis",
632 .id = 2,
633 .parent = &clk_p,
634 .enable = s5pc1xx_clk_d15_ctrl,
635 .ctrlbit = S5PC100_CLKGATE_D15_IIS2,
636 }, {
637 .name = "ac97",
638 .id = -1,
639 .parent = &clk_p,
640 .enable = s5pc1xx_clk_d15_ctrl,
641 .ctrlbit = S5PC100_CLKGATE_D15_AC97,
642 }, {
643 .name = "pcm",
644 .id = 0,
645 .parent = &clk_p,
646 .enable = s5pc1xx_clk_d15_ctrl,
647 .ctrlbit = S5PC100_CLKGATE_D15_PCM0,
648 }, {
649 .name = "pcm",
650 .id = 1,
651 .parent = &clk_p,
652 .enable = s5pc1xx_clk_d15_ctrl,
653 .ctrlbit = S5PC100_CLKGATE_D15_PCM1,
654 }, {
655 .name = "spdif",
656 .id = -1,
657 .parent = &clk_p,
658 .enable = s5pc1xx_clk_d15_ctrl,
659 .ctrlbit = S5PC100_CLKGATE_D15_SPDIF,
660 }, {
661 .name = "adc",
662 .id = -1,
663 .parent = &clk_p,
664 .enable = s5pc1xx_clk_d15_ctrl,
665 .ctrlbit = S5PC100_CLKGATE_D15_TSADC,
666 }, {
667 .name = "keyif",
668 .id = -1,
669 .parent = &clk_p,
670 .enable = s5pc1xx_clk_d15_ctrl,
671 .ctrlbit = S5PC100_CLKGATE_D15_KEYIF,
672 }, {
673 .name = "cg",
674 .id = -1,
675 .parent = &clk_p,
676 .enable = s5pc1xx_clk_d15_ctrl,
677 .ctrlbit = S5PC100_CLKGATE_D15_CG,
678 },
679
680 /* Audio (D2_0) devices: all disabled */
681
682 /* Special Clocks 1 */
683 {
684 .name = "sclk_hpm",
685 .id = -1,
686 .parent = NULL,
687 .enable = s5pc1xx_sclk0_ctrl,
688 .ctrlbit = S5PC1XX_CLKGATE_SCLK0_HPM,
689 }, {
690 .name = "sclk_onenand",
691 .id = -1,
692 .parent = NULL,
693 .enable = s5pc1xx_sclk0_ctrl,
694 .ctrlbit = S5PC100_CLKGATE_SCLK0_ONENAND,
695 }, {
696 .name = "sclk_spi_48",
697 .id = 0,
698 .parent = &clk_48m,
699 .enable = s5pc1xx_sclk0_ctrl,
700 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0_48,
701 }, {
702 .name = "sclk_spi_48",
703 .id = 1,
704 .parent = &clk_48m,
705 .enable = s5pc1xx_sclk0_ctrl,
706 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1_48,
707 }, {
708 .name = "sclk_spi_48",
709 .id = 2,
710 .parent = &clk_48m,
711 .enable = s5pc1xx_sclk0_ctrl,
712 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2_48,
713 }, {
714 .name = "sclk_mmc_48",
715 .id = 0,
716 .parent = &clk_48m,
717 .enable = s5pc1xx_sclk0_ctrl,
718 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0_48,
719 }, {
720 .name = "sclk_mmc_48",
721 .id = 1,
722 .parent = &clk_48m,
723 .enable = s5pc1xx_sclk0_ctrl,
724 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1_48,
725 }, {
726 .name = "sclk_mmc_48",
727 .id = 2,
728 .parent = &clk_48m,
729 .enable = s5pc1xx_sclk0_ctrl,
730 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2_48,
731 },
732
733 /* Special Clocks 2 */
734 {
735 .name = "sclk_tv_54",
736 .id = -1,
737 .parent = &clk_54m,
738 .enable = s5pc1xx_sclk1_ctrl,
739 .ctrlbit = S5PC100_CLKGATE_SCLK1_TV54,
740 }, {
741 .name = "sclk_vdac_54",
742 .id = -1,
743 .parent = &clk_54m,
744 .enable = s5pc1xx_sclk1_ctrl,
745 .ctrlbit = S5PC100_CLKGATE_SCLK1_VDAC54,
746 }, {
747 .name = "sclk_spdif",
748 .id = -1,
749 .parent = NULL,
750 .enable = s5pc1xx_sclk1_ctrl,
751 .ctrlbit = S5PC100_CLKGATE_SCLK1_SPDIF,
752 },
753};
754
755void __init s5pc1xx_register_clocks(void)
756{
757 struct clk *clkp;
758 int ret;
759 int ptr;
760
761 clkp = init_clocks;
762 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
763 ret = s3c24xx_register_clock(clkp);
764 if (ret < 0) {
765 printk(KERN_ERR "Failed to register clock %s (%d)\n",
766 clkp->name, ret);
767 }
768 }
769
770 clkp = init_clocks_disable;
771 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
772
773 ret = s3c24xx_register_clock(clkp);
774 if (ret < 0) {
775 printk(KERN_ERR "Failed to register clock %s (%d)\n",
776 clkp->name, ret);
777 }
778
779 (clkp->enable)(clkp, 0);
780 }
781
782 s3c_pwmclk_init();
783}
784static struct clk clk_fout_apll = {
785 .name = "fout_apll",
786 .id = -1,
787};
788
789static struct clk *clk_src_apll_list[] = {
790 [0] = &clk_fin_apll,
791 [1] = &clk_fout_apll,
792};
793
794static struct clk_sources clk_src_apll = {
795 .sources = clk_src_apll_list,
796 .nr_sources = ARRAY_SIZE(clk_src_apll_list),
797};
798
799static struct clksrc_clk clk_mout_apll = {
800 .clk = {
801 .name = "mout_apll",
802 .id = -1,
803 },
804 .shift = S5PC1XX_CLKSRC0_APLL_SHIFT,
805 .mask = S5PC1XX_CLKSRC0_APLL_MASK,
806 .sources = &clk_src_apll,
807 .reg_source = S5PC1XX_CLK_SRC0,
808};
809
810static struct clk clk_fout_epll = {
811 .name = "fout_epll",
812 .id = -1,
813};
814
815static struct clk *clk_src_epll_list[] = {
816 [0] = &clk_fin_epll,
817 [1] = &clk_fout_epll,
818};
819
820static struct clk_sources clk_src_epll = {
821 .sources = clk_src_epll_list,
822 .nr_sources = ARRAY_SIZE(clk_src_epll_list),
823};
824
825static struct clksrc_clk clk_mout_epll = {
826 .clk = {
827 .name = "mout_epll",
828 .id = -1,
829 },
830 .shift = S5PC1XX_CLKSRC0_EPLL_SHIFT,
831 .mask = S5PC1XX_CLKSRC0_EPLL_MASK,
832 .sources = &clk_src_epll,
833 .reg_source = S5PC1XX_CLK_SRC0,
834};
835
836static struct clk *clk_src_mpll_list[] = {
837 [0] = &clk_fin_mpll,
838 [1] = &clk_fout_mpll,
839};
840
841static struct clk_sources clk_src_mpll = {
842 .sources = clk_src_mpll_list,
843 .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
844};
845
846static struct clksrc_clk clk_mout_mpll = {
847 .clk = {
848 .name = "mout_mpll",
849 .id = -1,
850 },
851 .shift = S5PC1XX_CLKSRC0_MPLL_SHIFT,
852 .mask = S5PC1XX_CLKSRC0_MPLL_MASK,
853 .sources = &clk_src_mpll,
854 .reg_source = S5PC1XX_CLK_SRC0,
855};
856
857static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
858{
859 unsigned long rate = clk_get_rate(clk->parent);
860 unsigned long clkdiv;
861
862 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
863
864 clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
865 rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
866
867 return rate;
868}
869
870static struct clk clk_dout_mpll = {
871 .name = "dout_mpll",
872 .id = -1,
873 .parent = &clk_mout_mpll.clk,
874 .get_rate = s5pc1xx_clk_doutmpll_get_rate,
875};
876
877static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
878{
879 unsigned long rate = clk_get_rate(clk->parent);
880 unsigned long clkdiv;
881
882 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
883
884 clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
885 rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
886
887 return rate;
888}
889
890struct clk clk_dout_mpll2 = {
891 .name = "dout_mpll2",
892 .id = -1,
893 .parent = &clk_mout_mpll.clk,
894 .get_rate = s5pc1xx_clk_doutmpll2_get_rate,
895};
896
897static struct clk *clkset_uart_list[] = {
898 &clk_mout_epll.clk,
899 &clk_dout_mpll,
900 NULL,
901 NULL
902};
903
904static struct clk_sources clkset_uart = {
905 .sources = clkset_uart_list,
906 .nr_sources = ARRAY_SIZE(clkset_uart_list),
907};
908
909static inline struct clksrc_clk *to_clksrc(struct clk *clk)
910{
911 return container_of(clk, struct clksrc_clk, clk);
912}
913
914static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
915{
916 struct clksrc_clk *sclk = to_clksrc(clk);
917 unsigned long rate = clk_get_rate(clk->parent);
918 u32 clkdiv = __raw_readl(sclk->reg_divider);
919
920 clkdiv >>= sclk->divider_shift;
921 clkdiv &= 0xf;
922 clkdiv++;
923
924 rate /= clkdiv;
925 return rate;
926}
927
928static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
929{
930 struct clksrc_clk *sclk = to_clksrc(clk);
931 void __iomem *reg = sclk->reg_divider;
932 unsigned int div;
933 u32 val;
934
935 rate = clk_round_rate(clk, rate);
936 div = clk_get_rate(clk->parent) / rate;
937 if (div > 16)
938 return -EINVAL;
939
940 val = __raw_readl(reg);
941 val &= ~(0xf << sclk->shift);
942 val |= (div - 1) << sclk->shift;
943 __raw_writel(val, reg);
944
945 return 0;
946}
947
948static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
949{
950 struct clksrc_clk *sclk = to_clksrc(clk);
951 struct clk_sources *srcs = sclk->sources;
952 u32 clksrc = __raw_readl(sclk->reg_source);
953 int src_nr = -1;
954 int ptr;
955
956 for (ptr = 0; ptr < srcs->nr_sources; ptr++)
957 if (srcs->sources[ptr] == parent) {
958 src_nr = ptr;
959 break;
960 }
961
962 if (src_nr >= 0) {
963 clksrc &= ~sclk->mask;
964 clksrc |= src_nr << sclk->shift;
965
966 __raw_writel(clksrc, sclk->reg_source);
967 return 0;
968 }
969
970 return -EINVAL;
971}
972
973static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
974 unsigned long rate)
975{
976 unsigned long parent_rate = clk_get_rate(clk->parent);
977 int div;
978
979 if (rate > parent_rate)
980 rate = parent_rate;
981 else {
982 div = rate / parent_rate;
983
984 if (div == 0)
985 div = 1;
986 if (div > 16)
987 div = 16;
988
989 rate = parent_rate / div;
990 }
991
992 return rate;
993}
994
995static struct clksrc_clk clk_uart_uclk1 = {
996 .clk = {
997 .name = "uclk1",
998 .id = -1,
999 .ctrlbit = S5PC100_CLKGATE_SCLK0_UART,
1000 .enable = s5pc1xx_sclk0_ctrl,
1001 .set_parent = s5pc1xx_setparent_clksrc,
1002 .get_rate = s5pc1xx_getrate_clksrc,
1003 .set_rate = s5pc1xx_setrate_clksrc,
1004 .round_rate = s5pc1xx_roundrate_clksrc,
1005 },
1006 .shift = S5PC100_CLKSRC1_UART_SHIFT,
1007 .mask = S5PC100_CLKSRC1_UART_MASK,
1008 .sources = &clkset_uart,
1009 .divider_shift = S5PC100_CLKDIV2_UART_SHIFT,
1010 .reg_divider = S5PC1XX_CLK_DIV2,
1011 .reg_source = S5PC1XX_CLK_SRC1,
1012};
1013
1014/* Clock initialisation code */
1015
1016static struct clksrc_clk *init_parents[] = {
1017 &clk_mout_apll,
1018 &clk_mout_epll,
1019 &clk_mout_mpll,
1020 &clk_uart_uclk1,
1021};
1022
1023static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
1024{
1025 struct clk_sources *srcs = clk->sources;
1026 u32 clksrc = __raw_readl(clk->reg_source);
1027
1028 clksrc &= clk->mask;
1029 clksrc >>= clk->shift;
1030
1031 if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
1032 printk(KERN_ERR "%s: bad source %d\n",
1033 clk->clk.name, clksrc);
1034 return;
1035 }
1036
1037 clk->clk.parent = srcs->sources[clksrc];
1038
1039 printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
1040 clk->clk.name, clk->clk.parent->name, clksrc,
1041 clk_get_rate(&clk->clk));
1042}
1043
1044#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
1045
1046void __init_or_cpufreq s5pc100_setup_clocks(void)
1047{
1048 struct clk *xtal_clk;
1049 unsigned long xtal;
1050 unsigned long armclk;
1051 unsigned long hclkd0;
1052 unsigned long hclk;
1053 unsigned long pclkd0;
1054 unsigned long pclk;
1055 unsigned long apll;
1056 unsigned long mpll;
1057 unsigned long hpll;
1058 unsigned long epll;
1059 unsigned int ptr;
1060 u32 clkdiv0, clkdiv1;
1061
1062 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1063
1064 clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
1065 clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
1066
1067 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1068 __func__, clkdiv0, clkdiv1);
1069
1070 xtal_clk = clk_get(NULL, "xtal");
1071 BUG_ON(IS_ERR(xtal_clk));
1072
1073 xtal = clk_get_rate(xtal_clk);
1074 clk_put(xtal_clk);
1075
1076 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1077
1078 apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
1079 mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
1080 epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
1081 hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
1082
1083 printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
1084 apll, mpll, epll, hpll);
1085
1086 armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
1087 armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
1088 hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
1089 pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
1090 hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
1091 pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
1092
1093 printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
1094 armclk, hclkd0, pclkd0, hclk, pclk);
1095
1096 clk_fout_apll.rate = apll;
1097 clk_fout_mpll.rate = mpll;
1098 clk_fout_epll.rate = epll;
1099 clk_fout_apll.rate = apll;
1100
1101 clk_h.rate = hclk;
1102 clk_p.rate = pclk;
1103
1104 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
1105 s5pc1xx_set_clksrc(init_parents[ptr]);
1106}
1107
1108static struct clk *clks[] __initdata = {
1109 &clk_ext_xtal_mux,
1110 &clk_mout_epll.clk,
1111 &clk_fout_epll,
1112 &clk_mout_mpll.clk,
1113 &clk_dout_mpll,
1114 &clk_uart_uclk1.clk,
1115 &clk_ext,
1116 &clk_epll,
1117 &clk_27m,
1118 &clk_48m,
1119 &clk_54m,
1120};
1121
1122void __init s5pc100_register_clocks(void)
1123{
1124 struct clk *clkp;
1125 int ret;
1126 int ptr;
1127
1128 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
1129 clkp = clks[ptr];
1130 ret = s3c24xx_register_clock(clkp);
1131 if (ret < 0) {
1132 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1133 clkp->name, ret);
1134 }
1135 }
1136
1137 clk_mpll.parent = &clk_mout_mpll.clk;
1138 clk_epll.parent = &clk_mout_epll.clk;
1139}
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-init.c b/arch/arm/plat-s5pc1xx/s5pc100-init.c
new file mode 100644
index 000000000000..c58710884ceb
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/s5pc100-init.c
@@ -0,0 +1,27 @@
1/* linux/arch/arm/plat-s5pc1xx/s5pc100-init.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - CPU initialisation (common with other S5PC1XX chips)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/init.h>
16
17#include <plat/cpu.h>
18#include <plat/devs.h>
19#include <plat/s5pc100.h>
20
21/* uart registration process */
22
23void __init s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
24{
25 /* The driver name is s3c6400-uart to reuse s3c6400_serial_drv */
26 s3c24xx_init_uartdevs("s3c6400-uart", s5pc1xx_uart_resources, cfg, no);
27}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c
new file mode 100644
index 000000000000..3d00c025fffb
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-i2c0.c
@@ -0,0 +1,25 @@
1/* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Base S5PC1XX I2C bus 0 gpio configuration
7 *
8 * Based on plat-s3c64xx/setup-i2c0.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17
18struct platform_device; /* don't need the contents */
19
20#include <plat/iic.h>
21
22void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{
24 /* Pin configuration would be needed */
25}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c
new file mode 100644
index 000000000000..c8f3ca42f51d
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-i2c1.c
@@ -0,0 +1,25 @@
1/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Base S5PC1XX I2C bus 1 gpio configuration
7 *
8 * Based on plat-s3c64xx/setup-i2c1.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17
18struct platform_device; /* don't need the contents */
19
20#include <plat/iic.h>
21
22void s3c_i2c1_cfg_gpio(struct platform_device *dev)
23{
24 /* Pin configuration would be needed */
25}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 33026eff2aa4..c8c55b469342 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
12# 12#
13# http://www.arm.linux.org.uk/developer/machines/?action=new 13# http://www.arm.linux.org.uk/developer/machines/?action=new
14# 14#
15# Last update: Sat Jun 20 22:28:39 2009 15# Last update: Sat Sep 12 12:00:16 2009
16# 16#
17# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number 17# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
18# 18#
@@ -1769,7 +1769,7 @@ mx31cicada MACH_MX31CICADA MX31CICADA 1777
1769mi424wr MACH_MI424WR MI424WR 1778 1769mi424wr MACH_MI424WR MI424WR 1778
1770axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779 1770axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779
1771at572d940deb MACH_AT572D940DEB AT572D940DEB 1780 1771at572d940deb MACH_AT572D940DEB AT572D940DEB 1780
1772davinci_da8xx_evm MACH_DAVINCI_DA8XX_EVM DAVINCI_DA8XX_EVM 1781 1772davinci_da830_evm MACH_DAVINCI_DA830_EVM DAVINCI_DA830_EVM 1781
1773ep9302 MACH_EP9302 EP9302 1782 1773ep9302 MACH_EP9302 EP9302 1782
1774at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783 1774at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783
1775cybook3 MACH_CYBOOK3 CYBOOK3 1784 1775cybook3 MACH_CYBOOK3 CYBOOK3 1784
@@ -1962,7 +1962,7 @@ ethernut5 MACH_ETHERNUT5 ETHERNUT5 1971
1962arm11 MACH_ARM11 ARM11 1972 1962arm11 MACH_ARM11 ARM11 1972
1963cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 1963cpuat9260 MACH_CPUAT9260 CPUAT9260 1973
1964cpupxa255 MACH_CPUPXA255 CPUPXA255 1974 1964cpupxa255 MACH_CPUPXA255 CPUPXA255 1974
1965cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 1965eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975
1966cheflux MACH_CHEFLUX CHEFLUX 1976 1966cheflux MACH_CHEFLUX CHEFLUX 1976
1967eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977 1967eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977
1968opcotec MACH_OPCOTEC OPCOTEC 1978 1968opcotec MACH_OPCOTEC OPCOTEC 1978
@@ -2249,14 +2249,14 @@ omap3_phrazer MACH_OMAP3_PHRAZER OMAP3_PHRAZER 2261
2249darwin MACH_DARWIN DARWIN 2262 2249darwin MACH_DARWIN DARWIN 2262
2250oratiscomu MACH_ORATISCOMU ORATISCOMU 2263 2250oratiscomu MACH_ORATISCOMU ORATISCOMU 2263
2251rtsbc20 MACH_RTSBC20 RTSBC20 2264 2251rtsbc20 MACH_RTSBC20 RTSBC20 2264
2252i780 MACH_I780 I780 2265 2252sgh_i780 MACH_I780 I780 2265
2253gemini324 MACH_GEMINI324 GEMINI324 2266 2253gemini324 MACH_GEMINI324 GEMINI324 2266
2254oratislan MACH_ORATISLAN ORATISLAN 2267 2254oratislan MACH_ORATISLAN ORATISLAN 2267
2255oratisalog MACH_ORATISALOG ORATISALOG 2268 2255oratisalog MACH_ORATISALOG ORATISALOG 2268
2256oratismadi MACH_ORATISMADI ORATISMADI 2269 2256oratismadi MACH_ORATISMADI ORATISMADI 2269
2257oratisot16 MACH_ORATISOT16 ORATISOT16 2270 2257oratisot16 MACH_ORATISOT16 ORATISOT16 2270
2258oratisdesk MACH_ORATISDESK ORATISDESK 2271 2258oratisdesk MACH_ORATISDESK ORATISDESK 2271
2259v2p_ca9 MACH_V2P_CA9 V2P_CA9 2272 2259v2_ca9 MACH_V2P_CA9 V2P_CA9 2272
2260sintexo MACH_SINTEXO SINTEXO 2273 2260sintexo MACH_SINTEXO SINTEXO 2273
2261cm3389 MACH_CM3389 CM3389 2274 2261cm3389 MACH_CM3389 CM3389 2274
2262omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275 2262omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275
@@ -2280,3 +2280,132 @@ htcrhodium MACH_HTCRHODIUM HTCRHODIUM 2292
2280htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293 2280htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293
2281matrix504 MACH_MATRIX504 MATRIX504 2294 2281matrix504 MACH_MATRIX504 MATRIX504 2294
2282mrfsa MACH_MRFSA MRFSA 2295 2282mrfsa MACH_MRFSA MRFSA 2295
2283sc_p270 MACH_SC_P270 SC_P270 2296
2284atlas5_evb MACH_ATLAS5_EVB ATLAS5_EVB 2297
2285pelco_lobox MACH_PELCO_LOBOX PELCO_LOBOX 2298
2286dilax_pcu200 MACH_DILAX_PCU200 DILAX_PCU200 2299
2287leonardo MACH_LEONARDO LEONARDO 2300
2288zoran_approach7 MACH_ZORAN_APPROACH7 ZORAN_APPROACH7 2301
2289dp6xx MACH_DP6XX DP6XX 2302
2290bcm2153_vesper MACH_BCM2153_VESPER BCM2153_VESPER 2303
2291mahimahi MACH_MAHIMAHI MAHIMAHI 2304
2292clickc MACH_CLICKC CLICKC 2305
2293zb_gateway MACH_ZB_GATEWAY ZB_GATEWAY 2306
2294tazcard MACH_TAZCARD TAZCARD 2307
2295tazdev MACH_TAZDEV TAZDEV 2308
2296annax_cb_arm MACH_ANNAX_CB_ARM ANNAX_CB_ARM 2309
2297annax_dm3 MACH_ANNAX_DM3 ANNAX_DM3 2310
2298cerebric MACH_CEREBRIC CEREBRIC 2311
2299orca MACH_ORCA ORCA 2312
2300pc9260 MACH_PC9260 PC9260 2313
2301ems285a MACH_EMS285A EMS285A 2314
2302gec2410 MACH_GEC2410 GEC2410 2315
2303gec2440 MACH_GEC2440 GEC2440 2316
2304mw903 MACH_ARCH_MW903 ARCH_MW903 2317
2305mw2440 MACH_MW2440 MW2440 2318
2306ecac2378 MACH_ECAC2378 ECAC2378 2319
2307tazkiosk MACH_TAZKIOSK TAZKIOSK 2320
2308whiterabbit_mch MACH_WHITERABBIT_MCH WHITERABBIT_MCH 2321
2309sbox9263 MACH_SBOX9263 SBOX9263 2322
2310oreo MACH_OREO OREO 2323
2311smdk6442 MACH_SMDK6442 SMDK6442 2324
2312openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325
2313incredible MACH_INCREDIBLE INCREDIBLE 2326
2314incrediblec MACH_INCREDIBLEC INCREDIBLEC 2327
2315heroct MACH_HEROCT HEROCT 2328
2316mmnet1000 MACH_MMNET1000 MMNET1000 2329
2317devkit8000 MACH_DEVKIT8000 DEVKIT8000 2330
2318devkit9000 MACH_DEVKIT9000 DEVKIT9000 2331
2319mx31txtr MACH_MX31TXTR MX31TXTR 2332
2320u380 MACH_U380 U380 2333
2321oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334
2322npcmx50 MACH_NPCMX50 NPCMX50 2335
2323mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336
2324mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337
2325riom MACH_RIOM RIOM 2338
2326comcas MACH_COMCAS COMCAS 2339
2327wsi_mx27 MACH_WSI_MX27 WSI_MX27 2340
2328cm_t35 MACH_CM_T35 CM_T35 2341
2329net2big MACH_NET2BIG NET2BIG 2342
2330motorola_a1600 MACH_MOTOROLA_A1600 MOTOROLA_A1600 2343
2331igep0020 MACH_IGEP0020 IGEP0020 2344
2332igep0010 MACH_IGEP0010 IGEP0010 2345
2333mv6281gtwge2 MACH_MV6281GTWGE2 MV6281GTWGE2 2346
2334scat100 MACH_SCAT100 SCAT100 2347
2335sanmina MACH_SANMINA SANMINA 2348
2336momento MACH_MOMENTO MOMENTO 2349
2337nuc9xx MACH_NUC9XX NUC9XX 2350
2338nuc910evb MACH_NUC910EVB NUC910EVB 2351
2339nuc920evb MACH_NUC920EVB NUC920EVB 2352
2340nuc950evb MACH_NUC950EVB NUC950EVB 2353
2341nuc945evb MACH_NUC945EVB NUC945EVB 2354
2342nuc960evb MACH_NUC960EVB NUC960EVB 2355
2343nuc932evb MACH_NUC932EVB NUC932EVB 2356
2344nuc900 MACH_NUC900 NUC900 2357
2345sd1soc MACH_SD1SOC SD1SOC 2358
2346ln2440bc MACH_LN2440BC LN2440BC 2359
2347rsbc MACH_RSBC RSBC 2360
2348openrd_client MACH_OPENRD_CLIENT OPENRD_CLIENT 2361
2349hpipaq11x MACH_HPIPAQ11X HPIPAQ11X 2362
2350wayland MACH_WAYLAND WAYLAND 2363
2351acnbsx102 MACH_ACNBSX102 ACNBSX102 2364
2352hwat91 MACH_HWAT91 HWAT91 2365
2353at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366
2354csb732 MACH_CSB732 CSB732 2367
2355u8500 MACH_U8500 U8500 2368
2356huqiu MACH_HUQIU HUQIU 2369
2357mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370
2358pmt1g MACH_PMT1G PMT1G 2371
2359htcelf MACH_HTCELF HTCELF 2372
2360armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373
2361armadillo440 MACH_ARMADILLO440 ARMADILLO440 2374
2362u_chip_dual_arm MACH_U_CHIP_DUAL_ARM U_CHIP_DUAL_ARM 2375
2363csr_bdb3 MACH_CSR_BDB3 CSR_BDB3 2376
2364dolby_cat1018 MACH_DOLBY_CAT1018 DOLBY_CAT1018 2377
2365hy9307 MACH_HY9307 HY9307 2378
2366aspire_easystore MACH_A_ES A_ES 2379
2367davinci_irif MACH_DAVINCI_IRIF DAVINCI_IRIF 2380
2368agama9263 MACH_AGAMA9263 AGAMA9263 2381
2369marvell_jasper MACH_MARVELL_JASPER MARVELL_JASPER 2382
2370flint MACH_FLINT FLINT 2383
2371tavorevb3 MACH_TAVOREVB3 TAVOREVB3 2384
2372sch_m490 MACH_SCH_M490 SCH_M490 2386
2373rbl01 MACH_RBL01 RBL01 2387
2374omnifi MACH_OMNIFI OMNIFI 2388
2375otavalo MACH_OTAVALO OTAVALO 2389
2376sienna MACH_SIENNA SIENNA 2390
2377htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391
2378htc_opal MACH_HTC_OPAL HTC_OPAL 2392
2379touchbook MACH_TOUCHBOOK TOUCHBOOK 2393
2380latte MACH_LATTE LATTE 2394
2381xa200 MACH_XA200 XA200 2395
2382nimrod MACH_NIMROD NIMROD 2396
2383cc9p9215_3g MACH_CC9P9215_3G CC9P9215_3G 2397
2384cc9p9215_3gjs MACH_CC9P9215_3GJS CC9P9215_3GJS 2398
2385tk71 MACH_TK71 TK71 2399
2386comham3525 MACH_COMHAM3525 COMHAM3525 2400
2387mx31erebus MACH_MX31EREBUS MX31EREBUS 2401
2388mcardmx27 MACH_MCARDMX27 MCARDMX27 2402
2389paradise MACH_PARADISE PARADISE 2403
2390tide MACH_TIDE TIDE 2404
2391wzl2440 MACH_WZL2440 WZL2440 2405
2392sdrdemo MACH_SDRDEMO SDRDEMO 2406
2393ethercan2 MACH_ETHERCAN2 ETHERCAN2 2407
2394ecmimg20 MACH_ECMIMG20 ECMIMG20 2408
2395omap_dragon MACH_OMAP_DRAGON OMAP_DRAGON 2409
2396halo MACH_HALO HALO 2410
2397huangshan MACH_HUANGSHAN HUANGSHAN 2411
2398vl_ma2sc MACH_VL_MA2SC VL_MA2SC 2412
2399raumfeld_rc MACH_RAUMFELD_RC RAUMFELD_RC 2413
2400raumfeld_connector MACH_RAUMFELD_CONNECTOR RAUMFELD_CONNECTOR 2414
2401raumfeld_speaker MACH_RAUMFELD_SPEAKER RAUMFELD_SPEAKER 2415
2402multibus_master MACH_MULTIBUS_MASTER MULTIBUS_MASTER 2416
2403multibus_pbk MACH_MULTIBUS_PBK MULTIBUS_PBK 2417
2404tnetv107x MACH_TNETV107X TNETV107X 2418
2405snake MACH_SNAKE SNAKE 2419
2406cwmx27 MACH_CWMX27 CWMX27 2420
2407sch_m480 MACH_SCH_M480 SCH_M480 2421
2408platypus MACH_PLATYPUS PLATYPUS 2422
2409pss2 MACH_PSS2 PSS2 2423
2410davinci_apm150 MACH_DAVINCI_APM150 DAVINCI_APM150 2424
2411str9100 MACH_STR9100 STR9100 2425
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index a2bed62aec21..4fa9903b83cf 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -42,6 +42,7 @@ ENTRY(vfp_null_entry)
42 mov pc, lr 42 mov pc, lr
43ENDPROC(vfp_null_entry) 43ENDPROC(vfp_null_entry)
44 44
45 .align 2
45.LCvfp: 46.LCvfp:
46 .word vfp_vector 47 .word vfp_vector
47 48
@@ -61,6 +62,7 @@ ENTRY(vfp_testing_entry)
61 mov pc, r9 @ we have handled the fault 62 mov pc, r9 @ we have handled the fault
62ENDPROC(vfp_testing_entry) 63ENDPROC(vfp_testing_entry)
63 64
65 .align 2
64VFP_arch_address: 66VFP_arch_address:
65 .word VFP_arch 67 .word VFP_arch
66 68
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 1aeae38725dd..66dc2d03b7fc 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -209,40 +209,55 @@ ENDPROC(vfp_save_state)
209last_VFP_context_address: 209last_VFP_context_address:
210 .word last_VFP_context 210 .word last_VFP_context
211 211
212ENTRY(vfp_get_float) 212 .macro tbl_branch, base, tmp, shift
213 add pc, pc, r0, lsl #3 213#ifdef CONFIG_THUMB2_KERNEL
214 adr \tmp, 1f
215 add \tmp, \tmp, \base, lsl \shift
216 mov pc, \tmp
217#else
218 add pc, pc, \base, lsl \shift
214 mov r0, r0 219 mov r0, r0
220#endif
2211:
222 .endm
223
224ENTRY(vfp_get_float)
225 tbl_branch r0, r3, #3
215 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 226 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
216 mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0 2271: mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0
217 mov pc, lr 228 mov pc, lr
218 mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1 229 .org 1b + 8
2301: mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1
219 mov pc, lr 231 mov pc, lr
232 .org 1b + 8
220 .endr 233 .endr
221ENDPROC(vfp_get_float) 234ENDPROC(vfp_get_float)
222 235
223ENTRY(vfp_put_float) 236ENTRY(vfp_put_float)
224 add pc, pc, r1, lsl #3 237 tbl_branch r1, r3, #3
225 mov r0, r0
226 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 238 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
227 mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0 2391: mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0
228 mov pc, lr 240 mov pc, lr
229 mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1 241 .org 1b + 8
2421: mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1
230 mov pc, lr 243 mov pc, lr
244 .org 1b + 8
231 .endr 245 .endr
232ENDPROC(vfp_put_float) 246ENDPROC(vfp_put_float)
233 247
234ENTRY(vfp_get_double) 248ENTRY(vfp_get_double)
235 add pc, pc, r0, lsl #3 249 tbl_branch r0, r3, #3
236 mov r0, r0
237 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 250 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
238 fmrrd r0, r1, d\dr 2511: fmrrd r0, r1, d\dr
239 mov pc, lr 252 mov pc, lr
253 .org 1b + 8
240 .endr 254 .endr
241#ifdef CONFIG_VFPv3 255#ifdef CONFIG_VFPv3
242 @ d16 - d31 registers 256 @ d16 - d31 registers
243 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 257 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
244 mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr 2581: mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr
245 mov pc, lr 259 mov pc, lr
260 .org 1b + 8
246 .endr 261 .endr
247#endif 262#endif
248 263
@@ -253,17 +268,18 @@ ENTRY(vfp_get_double)
253ENDPROC(vfp_get_double) 268ENDPROC(vfp_get_double)
254 269
255ENTRY(vfp_put_double) 270ENTRY(vfp_put_double)
256 add pc, pc, r2, lsl #3 271 tbl_branch r2, r3, #3
257 mov r0, r0
258 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 272 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
259 fmdrr d\dr, r0, r1 2731: fmdrr d\dr, r0, r1
260 mov pc, lr 274 mov pc, lr
275 .org 1b + 8
261 .endr 276 .endr
262#ifdef CONFIG_VFPv3 277#ifdef CONFIG_VFPv3
263 @ d16 - d31 registers 278 @ d16 - d31 registers
264 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 279 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
265 mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr 2801: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr
266 mov pc, lr 281 mov pc, lr
282 .org 1b + 8
267 .endr 283 .endr
268#endif 284#endif
269ENDPROC(vfp_put_double) 285ENDPROC(vfp_put_double)
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index 04c860619700..fe863f9794d5 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -57,4 +57,7 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* __ASM_AVR32_SOCKET_H */ 63#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h
index fc42de5ca209..fd0c5d7e9337 100644
--- a/arch/avr32/include/asm/thread_info.h
+++ b/arch/avr32/include/asm/thread_info.h
@@ -84,6 +84,7 @@ static inline struct thread_info *current_thread_info(void)
84#define TIF_MEMDIE 6 84#define TIF_MEMDIE 6
85#define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ 85#define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */
86#define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ 86#define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */
87#define TIF_NOTIFY_RESUME 9 /* callback before returning to user */
87#define TIF_FREEZE 29 88#define TIF_FREEZE 29
88#define TIF_DEBUG 30 /* debugging enabled */ 89#define TIF_DEBUG 30 /* debugging enabled */
89#define TIF_USERSPACE 31 /* true if FS sets userspace */ 90#define TIF_USERSPACE 31 /* true if FS sets userspace */
@@ -96,6 +97,7 @@ static inline struct thread_info *current_thread_info(void)
96#define _TIF_MEMDIE (1 << TIF_MEMDIE) 97#define _TIF_MEMDIE (1 << TIF_MEMDIE)
97#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 98#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
98#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) 99#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
100#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
99#define _TIF_FREEZE (1 << TIF_FREEZE) 101#define _TIF_FREEZE (1 << TIF_FREEZE)
100 102
101/* Note: The masks below must never span more than 16 bits! */ 103/* Note: The masks below must never span more than 16 bits! */
@@ -103,13 +105,15 @@ static inline struct thread_info *current_thread_info(void)
103/* work to do on interrupt/exception return */ 105/* work to do on interrupt/exception return */
104#define _TIF_WORK_MASK \ 106#define _TIF_WORK_MASK \
105 ((1 << TIF_SIGPENDING) \ 107 ((1 << TIF_SIGPENDING) \
108 | _TIF_NOTIFY_RESUME \
106 | (1 << TIF_NEED_RESCHED) \ 109 | (1 << TIF_NEED_RESCHED) \
107 | (1 << TIF_POLLING_NRFLAG) \ 110 | (1 << TIF_POLLING_NRFLAG) \
108 | (1 << TIF_BREAKPOINT) \ 111 | (1 << TIF_BREAKPOINT) \
109 | (1 << TIF_RESTORE_SIGMASK)) 112 | (1 << TIF_RESTORE_SIGMASK))
110 113
111/* work to do on any return to userspace */ 114/* work to do on any return to userspace */
112#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE)) 115#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \
116 _TIF_NOTIFY_RESUME)
113/* work to do on return from debug mode */ 117/* work to do on return from debug mode */
114#define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT)) 118#define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT))
115 119
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index 009a80155d67..169268c40ae2 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -281,7 +281,7 @@ syscall_exit_work:
281 ld.w r1, r0[TI_flags] 281 ld.w r1, r0[TI_flags]
282 rjmp 1b 282 rjmp 1b
283 283
2842: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK 2842: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME
285 tst r1, r2 285 tst r1, r2
286 breq 3f 286 breq 3f
287 unmask_interrupts 287 unmask_interrupts
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index 27227561bad6..64f886fac2ef 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -16,6 +16,7 @@
16#include <linux/ptrace.h> 16#include <linux/ptrace.h>
17#include <linux/unistd.h> 17#include <linux/unistd.h>
18#include <linux/freezer.h> 18#include <linux/freezer.h>
19#include <linux/tracehook.h>
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/ucontext.h> 22#include <asm/ucontext.h>
@@ -322,4 +323,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
322 323
323 if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 324 if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
324 do_signal(regs, &current->blocked, syscall); 325 do_signal(regs, &current->blocked, syscall);
326
327 if (ti->flags & _TIF_NOTIFY_RESUME) {
328 clear_thread_flag(TIF_NOTIFY_RESUME);
329 tracehook_notify_resume(regs);
330 if (current->replacement_session_keyring)
331 key_replace_session_keyring();
332 }
325} 333}
diff --git a/arch/blackfin/include/asm/bfin_rotary.h b/arch/blackfin/include/asm/bfin_rotary.h
new file mode 100644
index 000000000000..425ece64fd5e
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_rotary.h
@@ -0,0 +1,39 @@
1/*
2 * board initialization should put one of these structures into platform_data
3 * and place the bfin-rotary onto platform_bus named "bfin-rotary".
4 */
5
6#ifndef _BFIN_ROTARY_H
7#define _BFIN_ROTARY_H
8
9/* mode bitmasks */
10#define ROT_QUAD_ENC CNTMODE_QUADENC /* quadrature/grey code encoder mode */
11#define ROT_BIN_ENC CNTMODE_BINENC /* binary encoder mode */
12#define ROT_UD_CNT CNTMODE_UDCNT /* rotary counter mode */
13#define ROT_DIR_CNT CNTMODE_DIRCNT /* direction counter mode */
14
15#define ROT_DEBE DEBE /* Debounce Enable */
16
17#define ROT_CDGINV CDGINV /* CDG Pin Polarity Invert */
18#define ROT_CUDINV CUDINV /* CUD Pin Polarity Invert */
19#define ROT_CZMINV CZMINV /* CZM Pin Polarity Invert */
20
21struct bfin_rotary_platform_data {
22 /* set rotary UP KEY_### or BTN_### in case you prefer
23 * bfin-rotary to send EV_KEY otherwise set 0
24 */
25 unsigned int rotary_up_key;
26 /* set rotary DOWN KEY_### or BTN_### in case you prefer
27 * bfin-rotary to send EV_KEY otherwise set 0
28 */
29 unsigned int rotary_down_key;
30 /* set rotary BUTTON KEY_### or BTN_### */
31 unsigned int rotary_button_key;
32 /* set rotary Relative Axis REL_### in case you prefer
33 * bfin-rotary to send EV_REL otherwise set 0
34 */
35 unsigned int rotary_rel_code;
36 unsigned short debounce; /* 0..17 */
37 unsigned short mode;
38};
39#endif
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index d5cf74005408..45ec49bdb7b1 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -59,6 +59,9 @@
59#define SO_TIMESTAMPING 37 59#define SO_TIMESTAMPING 37
60#define SCM_TIMESTAMPING SO_TIMESTAMPING 60#define SCM_TIMESTAMPING SO_TIMESTAMPING
61 61
62#define SO_PROTOCOL 38
63#define SO_DOMAIN 39
64
62#endif /* _ASM_SOCKET_H */ 65#endif /* _ASM_SOCKET_H */
63 66
64 67
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
index b326023baab2..48b0f3912632 100644
--- a/arch/cris/kernel/ptrace.c
+++ b/arch/cris/kernel/ptrace.c
@@ -16,6 +16,7 @@
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/user.h> 18#include <linux/user.h>
19#include <linux/tracehook.h>
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/page.h> 22#include <asm/page.h>
@@ -36,4 +37,11 @@ void do_notify_resume(int canrestart, struct pt_regs *regs,
36 /* deal with pending signal delivery */ 37 /* deal with pending signal delivery */
37 if (thread_info_flags & _TIF_SIGPENDING) 38 if (thread_info_flags & _TIF_SIGPENDING)
38 do_signal(canrestart,regs); 39 do_signal(canrestart,regs);
40
41 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
42 clear_thread_flag(TIF_NOTIFY_RESUME);
43 tracehook_notify_resume(regs);
44 if (current->replacement_session_keyring)
45 key_replace_session_keyring();
46 }
39} 47}
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h
index 57c3d4054e8b..2dea726095c2 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/asm/socket.h
@@ -57,5 +57,8 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* _ASM_SOCKET_H */ 63#endif /* _ASM_SOCKET_H */
61 64
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 4a7a62c6e783..6b0a2b6fed6a 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -572,6 +572,8 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
572 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 572 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
573 clear_thread_flag(TIF_NOTIFY_RESUME); 573 clear_thread_flag(TIF_NOTIFY_RESUME);
574 tracehook_notify_resume(__frame); 574 tracehook_notify_resume(__frame);
575 if (current->replacement_session_keyring)
576 key_replace_session_keyring();
575 } 577 }
576 578
577} /* end do_notify_resume() */ 579} /* end do_notify_resume() */
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index 602518a70a1a..1547f01c8e22 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -57,4 +57,7 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* _ASM_SOCKET_H */ 63#endif /* _ASM_SOCKET_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index 8bbc8b0ee45d..70e67e47d020 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -89,6 +89,7 @@ static inline struct thread_info *current_thread_info(void)
89 TIF_NEED_RESCHED */ 89 TIF_NEED_RESCHED */
90#define TIF_MEMDIE 4 90#define TIF_MEMDIE 4
91#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ 91#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
92#define TIF_NOTIFY_RESUME 6 /* callback before returning to user */
92#define TIF_FREEZE 16 /* is freezing for suspend */ 93#define TIF_FREEZE 16 /* is freezing for suspend */
93 94
94/* as above, but as bit values */ 95/* as above, but as bit values */
@@ -97,6 +98,7 @@ static inline struct thread_info *current_thread_info(void)
97#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 98#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
98#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 99#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
99#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 100#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
101#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
100#define _TIF_FREEZE (1<<TIF_FREEZE) 102#define _TIF_FREEZE (1<<TIF_FREEZE)
101 103
102#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ 104#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index cf3472f7389b..af842c369d24 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -39,6 +39,7 @@
39#include <linux/tty.h> 39#include <linux/tty.h>
40#include <linux/binfmts.h> 40#include <linux/binfmts.h>
41#include <linux/freezer.h> 41#include <linux/freezer.h>
42#include <linux/tracehook.h>
42 43
43#include <asm/setup.h> 44#include <asm/setup.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -552,4 +553,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
552{ 553{
553 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 554 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
554 do_signal(regs, NULL); 555 do_signal(regs, NULL);
556
557 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
558 clear_thread_flag(TIF_NOTIFY_RESUME);
559 tracehook_notify_resume(regs);
560 if (current->replacement_session_keyring)
561 key_replace_session_keyring();
562 }
555} 563}
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index e4d8fde68103..7e81966ce481 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -412,7 +412,7 @@ simeth_tx(struct sk_buff *skb, struct net_device *dev)
412 */ 412 */
413 413
414 dev_kfree_skb(skb); 414 dev_kfree_skb(skb);
415 return 0; 415 return NETDEV_TX_OK;
416} 416}
417 417
418static inline struct sk_buff * 418static inline struct sk_buff *
diff --git a/arch/ia64/include/asm/device.h b/arch/ia64/include/asm/device.h
index 41ab85d66f33..d66d446b127c 100644
--- a/arch/ia64/include/asm/device.h
+++ b/arch/ia64/include/asm/device.h
@@ -15,4 +15,7 @@ struct dev_archdata {
15#endif 15#endif
16}; 16};
17 17
18struct pdev_archdata {
19};
20
18#endif /* _ASM_IA64_DEVICE_H */ 21#endif /* _ASM_IA64_DEVICE_H */
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 5a61b5c2e18f..8d3c79cd81e7 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -44,7 +44,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
44#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 44#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
45 45
46#define get_dma_ops(dev) platform_dma_get_ops(dev) 46#define get_dma_ops(dev) platform_dma_get_ops(dev)
47#define flush_write_buffers()
48 47
49#include <asm-generic/dma-mapping-common.h> 48#include <asm-generic/dma-mapping-common.h>
50 49
@@ -69,6 +68,24 @@ dma_set_mask (struct device *dev, u64 mask)
69 return 0; 68 return 0;
70} 69}
71 70
71static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
72{
73 if (!dev->dma_mask)
74 return 0;
75
76 return addr + size <= *dev->dma_mask;
77}
78
79static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
80{
81 return paddr;
82}
83
84static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
85{
86 return daddr;
87}
88
72extern int dma_get_cache_alignment(void); 89extern int dma_get_cache_alignment(void);
73 90
74static inline void 91static inline void
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 5f43697aed30..d9b6325a9328 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -235,7 +235,8 @@ struct kvm_vm_data {
235#define KVM_REQ_PTC_G 32 235#define KVM_REQ_PTC_G 32
236#define KVM_REQ_RESUME 33 236#define KVM_REQ_RESUME 33
237 237
238#define KVM_PAGES_PER_HPAGE 1 238#define KVM_NR_PAGE_SIZES 1
239#define KVM_PAGES_PER_HPAGE(x) 1
239 240
240struct kvm; 241struct kvm;
241struct kvm_vcpu; 242struct kvm_vcpu;
@@ -465,7 +466,6 @@ struct kvm_arch {
465 unsigned long metaphysical_rr4; 466 unsigned long metaphysical_rr4;
466 unsigned long vmm_init_rr; 467 unsigned long vmm_init_rr;
467 468
468 int online_vcpus;
469 int is_sn2; 469 int is_sn2;
470 470
471 struct kvm_ioapic *vioapic; 471 struct kvm_ioapic *vioapic;
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h
index 0d6d8ca07b8c..1588aee781a2 100644
--- a/arch/ia64/include/asm/kvm_para.h
+++ b/arch/ia64/include/asm/kvm_para.h
@@ -19,9 +19,13 @@
19 * 19 *
20 */ 20 */
21 21
22#ifdef __KERNEL__
23
22static inline unsigned int kvm_arch_para_features(void) 24static inline unsigned int kvm_arch_para_features(void)
23{ 25{
24 return 0; 26 return 0;
25} 27}
26 28
27#endif 29#endif
30
31#endif
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index 745421225ec6..0b0d5ff062e5 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -66,4 +66,7 @@
66#define SO_TIMESTAMPING 37 66#define SO_TIMESTAMPING 37
67#define SCM_TIMESTAMPING SO_TIMESTAMPING 67#define SCM_TIMESTAMPING SO_TIMESTAMPING
68 68
69#define SO_PROTOCOL 38
70#define SO_DOMAIN 39
71
69#endif /* _ASM_IA64_SOCKET_H */ 72#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index 23f846de62d5..e6c5c3d5e1f8 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -34,6 +34,7 @@
34#include <asm/mca_asm.h> 34#include <asm/mca_asm.h>
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/linkage.h> 36#include <linux/linkage.h>
37#include "head.h"
37 38
38#ifdef CONFIG_HOTPLUG_CPU 39#ifdef CONFIG_HOTPLUG_CPU
39#define SAL_PSR_BITS_TO_SET \ 40#define SAL_PSR_BITS_TO_SET \
diff --git a/arch/ia64/kernel/head.h b/arch/ia64/kernel/head.h
new file mode 100644
index 000000000000..2e2ac6824e65
--- /dev/null
+++ b/arch/ia64/kernel/head.h
@@ -0,0 +1 @@
extern void console_print(const char *s);
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 5d7c0e5b9e76..9bcec9945c12 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -161,6 +161,13 @@ show_regs (struct pt_regs *regs)
161 show_stack(NULL, NULL); 161 show_stack(NULL, NULL);
162} 162}
163 163
164/* local support for deprecated console_print */
165void
166console_print(const char *s)
167{
168 printk(KERN_EMERG "%s", s);
169}
170
164void 171void
165do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) 172do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
166{ 173{
@@ -192,6 +199,8 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
192 if (test_thread_flag(TIF_NOTIFY_RESUME)) { 199 if (test_thread_flag(TIF_NOTIFY_RESUME)) {
193 clear_thread_flag(TIF_NOTIFY_RESUME); 200 clear_thread_flag(TIF_NOTIFY_RESUME);
194 tracehook_notify_resume(&scr->pt); 201 tracehook_notify_resume(&scr->pt);
202 if (current->replacement_session_keyring)
203 key_replace_session_keyring();
195 } 204 }
196 205
197 /* copy user rbs to kernel rbs */ 206 /* copy user rbs to kernel rbs */
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 64d520937874..ef3e7be29caf 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -1,12 +1,8 @@
1# 1#
2# KVM configuration 2# KVM configuration
3# 3#
4config HAVE_KVM
5 bool
6 4
7config HAVE_KVM_IRQCHIP 5source "virt/kvm/Kconfig"
8 bool
9 default y
10 6
11menuconfig VIRTUALIZATION 7menuconfig VIRTUALIZATION
12 bool "Virtualization" 8 bool "Virtualization"
@@ -28,6 +24,8 @@ config KVM
28 depends on PCI 24 depends on PCI
29 select PREEMPT_NOTIFIERS 25 select PREEMPT_NOTIFIERS
30 select ANON_INODES 26 select ANON_INODES
27 select HAVE_KVM_IRQCHIP
28 select KVM_APIC_ARCHITECTURE
31 ---help--- 29 ---help---
32 Support hosting fully virtualized guest machines using hardware 30 Support hosting fully virtualized guest machines using hardware
33 virtualization extensions. You will need a fairly recent 31 virtualization extensions. You will need a fairly recent
@@ -49,9 +47,6 @@ config KVM_INTEL
49 Provides support for KVM on Itanium 2 processors equipped with the VT 47 Provides support for KVM on Itanium 2 processors equipped with the VT
50 extensions. 48 extensions.
51 49
52config KVM_TRACE
53 bool
54
55source drivers/virtio/Kconfig 50source drivers/virtio/Kconfig
56 51
57endif # VIRTUALIZATION 52endif # VIRTUALIZATION
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 80c57b0a21c4..0ad09f05efa9 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -210,16 +210,6 @@ int kvm_dev_ioctl_check_extension(long ext)
210 210
211} 211}
212 212
213static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
214 gpa_t addr, int len, int is_write)
215{
216 struct kvm_io_device *dev;
217
218 dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write);
219
220 return dev;
221}
222
223static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 213static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
224{ 214{
225 kvm_run->exit_reason = KVM_EXIT_UNKNOWN; 215 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
@@ -231,6 +221,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
231{ 221{
232 struct kvm_mmio_req *p; 222 struct kvm_mmio_req *p;
233 struct kvm_io_device *mmio_dev; 223 struct kvm_io_device *mmio_dev;
224 int r;
234 225
235 p = kvm_get_vcpu_ioreq(vcpu); 226 p = kvm_get_vcpu_ioreq(vcpu);
236 227
@@ -247,16 +238,13 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
247 kvm_run->exit_reason = KVM_EXIT_MMIO; 238 kvm_run->exit_reason = KVM_EXIT_MMIO;
248 return 0; 239 return 0;
249mmio: 240mmio:
250 mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir); 241 if (p->dir)
251 if (mmio_dev) { 242 r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr,
252 if (!p->dir) 243 p->size, &p->data);
253 kvm_iodevice_write(mmio_dev, p->addr, p->size, 244 else
254 &p->data); 245 r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr,
255 else 246 p->size, &p->data);
256 kvm_iodevice_read(mmio_dev, p->addr, p->size, 247 if (r)
257 &p->data);
258
259 } else
260 printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr); 248 printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
261 p->state = STATE_IORESP_READY; 249 p->state = STATE_IORESP_READY;
262 250
@@ -337,13 +325,12 @@ static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id,
337{ 325{
338 union ia64_lid lid; 326 union ia64_lid lid;
339 int i; 327 int i;
328 struct kvm_vcpu *vcpu;
340 329
341 for (i = 0; i < kvm->arch.online_vcpus; i++) { 330 kvm_for_each_vcpu(i, vcpu, kvm) {
342 if (kvm->vcpus[i]) { 331 lid.val = VCPU_LID(vcpu);
343 lid.val = VCPU_LID(kvm->vcpus[i]); 332 if (lid.id == id && lid.eid == eid)
344 if (lid.id == id && lid.eid == eid) 333 return vcpu;
345 return kvm->vcpus[i];
346 }
347 } 334 }
348 335
349 return NULL; 336 return NULL;
@@ -409,21 +396,21 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
409 struct kvm *kvm = vcpu->kvm; 396 struct kvm *kvm = vcpu->kvm;
410 struct call_data call_data; 397 struct call_data call_data;
411 int i; 398 int i;
399 struct kvm_vcpu *vcpui;
412 400
413 call_data.ptc_g_data = p->u.ptc_g_data; 401 call_data.ptc_g_data = p->u.ptc_g_data;
414 402
415 for (i = 0; i < kvm->arch.online_vcpus; i++) { 403 kvm_for_each_vcpu(i, vcpui, kvm) {
416 if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state == 404 if (vcpui->arch.mp_state == KVM_MP_STATE_UNINITIALIZED ||
417 KVM_MP_STATE_UNINITIALIZED || 405 vcpu == vcpui)
418 vcpu == kvm->vcpus[i])
419 continue; 406 continue;
420 407
421 if (waitqueue_active(&kvm->vcpus[i]->wq)) 408 if (waitqueue_active(&vcpui->wq))
422 wake_up_interruptible(&kvm->vcpus[i]->wq); 409 wake_up_interruptible(&vcpui->wq);
423 410
424 if (kvm->vcpus[i]->cpu != -1) { 411 if (vcpui->cpu != -1) {
425 call_data.vcpu = kvm->vcpus[i]; 412 call_data.vcpu = vcpui;
426 smp_call_function_single(kvm->vcpus[i]->cpu, 413 smp_call_function_single(vcpui->cpu,
427 vcpu_global_purge, &call_data, 1); 414 vcpu_global_purge, &call_data, 1);
428 } else 415 } else
429 printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); 416 printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n");
@@ -852,8 +839,6 @@ struct kvm *kvm_arch_create_vm(void)
852 839
853 kvm_init_vm(kvm); 840 kvm_init_vm(kvm);
854 841
855 kvm->arch.online_vcpus = 0;
856
857 return kvm; 842 return kvm;
858 843
859} 844}
@@ -1000,10 +985,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
1000 goto out; 985 goto out;
1001 if (irqchip_in_kernel(kvm)) { 986 if (irqchip_in_kernel(kvm)) {
1002 __s32 status; 987 __s32 status;
1003 mutex_lock(&kvm->lock); 988 mutex_lock(&kvm->irq_lock);
1004 status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 989 status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
1005 irq_event.irq, irq_event.level); 990 irq_event.irq, irq_event.level);
1006 mutex_unlock(&kvm->lock); 991 mutex_unlock(&kvm->irq_lock);
1007 if (ioctl == KVM_IRQ_LINE_STATUS) { 992 if (ioctl == KVM_IRQ_LINE_STATUS) {
1008 irq_event.status = status; 993 irq_event.status = status;
1009 if (copy_to_user(argp, &irq_event, 994 if (copy_to_user(argp, &irq_event,
@@ -1216,7 +1201,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
1216 if (IS_ERR(vmm_vcpu)) 1201 if (IS_ERR(vmm_vcpu))
1217 return PTR_ERR(vmm_vcpu); 1202 return PTR_ERR(vmm_vcpu);
1218 1203
1219 if (vcpu->vcpu_id == 0) { 1204 if (kvm_vcpu_is_bsp(vcpu)) {
1220 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; 1205 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
1221 1206
1222 /*Set entry address for first run.*/ 1207 /*Set entry address for first run.*/
@@ -1224,7 +1209,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
1224 1209
1225 /*Initialize itc offset for vcpus*/ 1210 /*Initialize itc offset for vcpus*/
1226 itc_offset = 0UL - kvm_get_itc(vcpu); 1211 itc_offset = 0UL - kvm_get_itc(vcpu);
1227 for (i = 0; i < kvm->arch.online_vcpus; i++) { 1212 for (i = 0; i < KVM_MAX_VCPUS; i++) {
1228 v = (struct kvm_vcpu *)((char *)vcpu + 1213 v = (struct kvm_vcpu *)((char *)vcpu +
1229 sizeof(struct kvm_vcpu_data) * i); 1214 sizeof(struct kvm_vcpu_data) * i);
1230 v->arch.itc_offset = itc_offset; 1215 v->arch.itc_offset = itc_offset;
@@ -1356,8 +1341,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
1356 goto fail; 1341 goto fail;
1357 } 1342 }
1358 1343
1359 kvm->arch.online_vcpus++;
1360
1361 return vcpu; 1344 return vcpu;
1362fail: 1345fail:
1363 return ERR_PTR(r); 1346 return ERR_PTR(r);
@@ -1952,19 +1935,6 @@ int kvm_highest_pending_irq(struct kvm_vcpu *vcpu)
1952 return find_highest_bits((int *)&vpd->irr[0]); 1935 return find_highest_bits((int *)&vpd->irr[0]);
1953} 1936}
1954 1937
1955int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
1956{
1957 if (kvm_highest_pending_irq(vcpu) != -1)
1958 return 1;
1959 return 0;
1960}
1961
1962int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
1963{
1964 /* do real check here */
1965 return 1;
1966}
1967
1968int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 1938int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
1969{ 1939{
1970 return vcpu->arch.timer_fired; 1940 return vcpu->arch.timer_fired;
@@ -1977,7 +1947,8 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
1977 1947
1978int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) 1948int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
1979{ 1949{
1980 return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE; 1950 return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) ||
1951 (kvm_highest_pending_irq(vcpu) != -1);
1981} 1952}
1982 1953
1983int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, 1954int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c
index cc406d064a09..dce75b70cdd5 100644
--- a/arch/ia64/kvm/vcpu.c
+++ b/arch/ia64/kvm/vcpu.c
@@ -830,8 +830,8 @@ static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
830 830
831 kvm = (struct kvm *)KVM_VM_BASE; 831 kvm = (struct kvm *)KVM_VM_BASE;
832 832
833 if (vcpu->vcpu_id == 0) { 833 if (kvm_vcpu_is_bsp(vcpu)) {
834 for (i = 0; i < kvm->arch.online_vcpus; i++) { 834 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) {
835 v = (struct kvm_vcpu *)((char *)vcpu + 835 v = (struct kvm_vcpu *)((char *)vcpu +
836 sizeof(struct kvm_vcpu_data) * i); 836 sizeof(struct kvm_vcpu_data) * i);
837 VMX(v, itc_offset) = itc_offset; 837 VMX(v, itc_offset) = itc_offset;
diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c
index fb8332690179..dbeadb9c8e20 100644
--- a/arch/ia64/xen/time.c
+++ b/arch/ia64/xen/time.c
@@ -133,8 +133,7 @@ consider_steal_time(unsigned long new_itm)
133 account_idle_ticks(blocked); 133 account_idle_ticks(blocked);
134 run_local_timers(); 134 run_local_timers();
135 135
136 if (rcu_pending(cpu)) 136 rcu_check_callbacks(cpu, user_mode(get_irq_regs()));
137 rcu_check_callbacks(cpu, user_mode(get_irq_regs()));
138 137
139 scheduler_tick(); 138 scheduler_tick();
140 run_posix_cpu_timers(p); 139 run_posix_cpu_timers(p);
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h
index be7ed589af5c..3390a864f224 100644
--- a/arch/m32r/include/asm/socket.h
+++ b/arch/m32r/include/asm/socket.h
@@ -57,4 +57,7 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* _ASM_M32R_SOCKET_H */ 63#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h
index 07bb5bd00e2a..71578151a403 100644
--- a/arch/m32r/include/asm/thread_info.h
+++ b/arch/m32r/include/asm/thread_info.h
@@ -149,6 +149,7 @@ static inline unsigned int get_thread_fault_code(void)
149#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ 149#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
150#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ 150#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
151#define TIF_IRET 4 /* return with iret */ 151#define TIF_IRET 4 /* return with iret */
152#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
152#define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */ 153#define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */
153#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 154#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
154#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 155#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
@@ -160,6 +161,7 @@ static inline unsigned int get_thread_fault_code(void)
160#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 161#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
161#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) 162#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
162#define _TIF_IRET (1<<TIF_IRET) 163#define _TIF_IRET (1<<TIF_IRET)
164#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
163#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 165#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
164#define _TIF_USEDFPU (1<<TIF_USEDFPU) 166#define _TIF_USEDFPU (1<<TIF_USEDFPU)
165#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 167#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 18124542a6eb..144b0f124fc7 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -21,6 +21,7 @@
21#include <linux/stddef.h> 21#include <linux/stddef.h>
22#include <linux/personality.h> 22#include <linux/personality.h>
23#include <linux/freezer.h> 23#include <linux/freezer.h>
24#include <linux/tracehook.h>
24#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
25#include <asm/ucontext.h> 26#include <asm/ucontext.h>
26#include <asm/uaccess.h> 27#include <asm/uaccess.h>
@@ -408,5 +409,12 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
408 if (thread_info_flags & _TIF_SIGPENDING) 409 if (thread_info_flags & _TIF_SIGPENDING)
409 do_signal(regs,oldset); 410 do_signal(regs,oldset);
410 411
412 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
413 clear_thread_flag(TIF_NOTIFY_RESUME);
414 tracehook_notify_resume(regs);
415 if (current->replacement_session_keyring)
416 key_replace_session_keyring();
417 }
418
411 clear_thread_flag(TIF_IRET); 419 clear_thread_flag(TIF_IRET);
412} 420}
diff --git a/arch/m68k/include/asm/entry_mm.h b/arch/m68k/include/asm/entry_mm.h
index 5202f5a5b420..474125886218 100644
--- a/arch/m68k/include/asm/entry_mm.h
+++ b/arch/m68k/include/asm/entry_mm.h
@@ -46,7 +46,6 @@
46#define curptr a2 46#define curptr a2
47 47
48LFLUSH_I_AND_D = 0x00000808 48LFLUSH_I_AND_D = 0x00000808
49LSIGTRAP = 5
50 49
51/* process bits for task_struct.ptrace */ 50/* process bits for task_struct.ptrace */
52PT_TRACESYS_OFF = 3 51PT_TRACESYS_OFF = 3
@@ -118,9 +117,6 @@ PT_DTRACE_BIT = 2
118#define STR(X) STR1(X) 117#define STR(X) STR1(X)
119#define STR1(X) #X 118#define STR1(X) #X
120 119
121#define PT_OFF_ORIG_D0 0x24
122#define PT_OFF_FORMATVEC 0x32
123#define PT_OFF_SR 0x2C
124#define SAVE_ALL_INT \ 120#define SAVE_ALL_INT \
125 "clrl %%sp@-;" /* stk_adj */ \ 121 "clrl %%sp@-;" /* stk_adj */ \
126 "pea -1:w;" /* orig d0 = -1 */ \ 122 "pea -1:w;" /* orig d0 = -1 */ \
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h
index c2553d26273d..907ed03d792f 100644
--- a/arch/m68k/include/asm/entry_no.h
+++ b/arch/m68k/include/asm/entry_no.h
@@ -72,8 +72,8 @@ LENOSYS = 38
72 lea %sp@(-32),%sp /* space for 8 regs */ 72 lea %sp@(-32),%sp /* space for 8 regs */
73 moveml %d1-%d5/%a0-%a2,%sp@ 73 moveml %d1-%d5/%a0-%a2,%sp@
74 movel sw_usp,%a0 /* get usp */ 74 movel sw_usp,%a0 /* get usp */
75 movel %a0@-,%sp@(PT_PC) /* copy exception program counter */ 75 movel %a0@-,%sp@(PT_OFF_PC) /* copy exception program counter */
76 movel %a0@-,%sp@(PT_FORMATVEC)/* copy exception format/vector/sr */ 76 movel %a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
77 bra 7f 77 bra 7f
78 6: 78 6:
79 clrl %sp@- /* stkadj */ 79 clrl %sp@- /* stkadj */
@@ -89,8 +89,8 @@ LENOSYS = 38
89 bnes 8f /* no, skip */ 89 bnes 8f /* no, skip */
90 move #0x2700,%sr /* disable intrs */ 90 move #0x2700,%sr /* disable intrs */
91 movel sw_usp,%a0 /* get usp */ 91 movel sw_usp,%a0 /* get usp */
92 movel %sp@(PT_PC),%a0@- /* copy exception program counter */ 92 movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
93 movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ 93 movel %sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
94 moveml %sp@,%d1-%d5/%a0-%a2 94 moveml %sp@,%d1-%d5/%a0-%a2
95 lea %sp@(32),%sp /* space for 8 regs */ 95 lea %sp@(32),%sp /* space for 8 regs */
96 movel %sp@+,%d0 96 movel %sp@+,%d0
diff --git a/arch/m68k/include/asm/math-emu.h b/arch/m68k/include/asm/math-emu.h
index ddfab96403cb..5e9249b0014c 100644
--- a/arch/m68k/include/asm/math-emu.h
+++ b/arch/m68k/include/asm/math-emu.h
@@ -145,16 +145,16 @@ extern unsigned int fp_debugprint;
145 * these are only used during instruction decoding 145 * these are only used during instruction decoding
146 * where we always know how deep we're on the stack. 146 * where we always know how deep we're on the stack.
147 */ 147 */
148#define FPS_DO (PT_D0) 148#define FPS_DO (PT_OFF_D0)
149#define FPS_D1 (PT_D1) 149#define FPS_D1 (PT_OFF_D1)
150#define FPS_D2 (PT_D2) 150#define FPS_D2 (PT_OFF_D2)
151#define FPS_A0 (PT_A0) 151#define FPS_A0 (PT_OFF_A0)
152#define FPS_A1 (PT_A1) 152#define FPS_A1 (PT_OFF_A1)
153#define FPS_A2 (PT_A2) 153#define FPS_A2 (PT_OFF_A2)
154#define FPS_SR (PT_SR) 154#define FPS_SR (PT_OFF_SR)
155#define FPS_PC (PT_PC) 155#define FPS_PC (PT_OFF_PC)
156#define FPS_EA (PT_PC+6) 156#define FPS_EA (PT_OFF_PC+6)
157#define FPS_PC2 (PT_PC+10) 157#define FPS_PC2 (PT_OFF_PC+10)
158 158
159.macro fp_get_fp_reg 159.macro fp_get_fp_reg
160 lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 160 lea (FPD_FPREG,FPDATA,%d0.w*4),%a0
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index ca87f938b03f..eee01cce921b 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -57,4 +57,7 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* _ASM_SOCKET_H */ 63#endif /* _ASM_SOCKET_H */
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
index 6ea5c33b3c56..b6da3882be9b 100644
--- a/arch/m68k/include/asm/thread_info_mm.h
+++ b/arch/m68k/include/asm/thread_info_mm.h
@@ -1,6 +1,10 @@
1#ifndef _ASM_M68K_THREAD_INFO_H 1#ifndef _ASM_M68K_THREAD_INFO_H
2#define _ASM_M68K_THREAD_INFO_H 2#define _ASM_M68K_THREAD_INFO_H
3 3
4#ifndef ASM_OFFSETS_C
5#include <asm/asm-offsets.h>
6#endif
7#include <asm/current.h>
4#include <asm/types.h> 8#include <asm/types.h>
5#include <asm/page.h> 9#include <asm/page.h>
6 10
@@ -31,7 +35,12 @@ struct thread_info {
31#define init_thread_info (init_task.thread.info) 35#define init_thread_info (init_task.thread.info)
32#define init_stack (init_thread_union.stack) 36#define init_stack (init_thread_union.stack)
33 37
34#define task_thread_info(tsk) (&(tsk)->thread.info) 38#ifdef ASM_OFFSETS_C
39#define task_thread_info(tsk) ((struct thread_info *) NULL)
40#else
41#define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_TINFO))
42#endif
43
35#define task_stack_page(tsk) ((tsk)->stack) 44#define task_stack_page(tsk) ((tsk)->stack)
36#define current_thread_info() task_thread_info(current) 45#define current_thread_info() task_thread_info(current)
37 46
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index b1f012f6c493..73e5e581245b 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -8,6 +8,8 @@
8 * #defines from the assembly-language output. 8 * #defines from the assembly-language output.
9 */ 9 */
10 10
11#define ASM_OFFSETS_C
12
11#include <linux/stddef.h> 13#include <linux/stddef.h>
12#include <linux/sched.h> 14#include <linux/sched.h>
13#include <linux/kernel_stat.h> 15#include <linux/kernel_stat.h>
@@ -27,6 +29,9 @@ int main(void)
27 DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); 29 DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
28 DEFINE(TASK_MM, offsetof(struct task_struct, mm)); 30 DEFINE(TASK_MM, offsetof(struct task_struct, mm));
29 DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); 31 DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
32#ifdef CONFIG_MMU
33 DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
34#endif
30 35
31 /* offsets into the thread struct */ 36 /* offsets into the thread struct */
32 DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); 37 DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
@@ -44,20 +49,20 @@ int main(void)
44 DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); 49 DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
45 50
46 /* offsets into the pt_regs */ 51 /* offsets into the pt_regs */
47 DEFINE(PT_D0, offsetof(struct pt_regs, d0)); 52 DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
48 DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); 53 DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
49 DEFINE(PT_D1, offsetof(struct pt_regs, d1)); 54 DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
50 DEFINE(PT_D2, offsetof(struct pt_regs, d2)); 55 DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
51 DEFINE(PT_D3, offsetof(struct pt_regs, d3)); 56 DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
52 DEFINE(PT_D4, offsetof(struct pt_regs, d4)); 57 DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
53 DEFINE(PT_D5, offsetof(struct pt_regs, d5)); 58 DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
54 DEFINE(PT_A0, offsetof(struct pt_regs, a0)); 59 DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
55 DEFINE(PT_A1, offsetof(struct pt_regs, a1)); 60 DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
56 DEFINE(PT_A2, offsetof(struct pt_regs, a2)); 61 DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
57 DEFINE(PT_PC, offsetof(struct pt_regs, pc)); 62 DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
58 DEFINE(PT_SR, offsetof(struct pt_regs, sr)); 63 DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
59 /* bitfields are a bit difficult */ 64 /* bitfields are a bit difficult */
60 DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); 65 DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
61 66
62 /* offsets into the irq_handler struct */ 67 /* offsets into the irq_handler struct */
63 DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler)); 68 DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
@@ -84,10 +89,10 @@ int main(void)
84 DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); 89 DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
85 90
86 /* signal defines */ 91 /* signal defines */
87 DEFINE(SIGSEGV, SIGSEGV); 92 DEFINE(LSIGSEGV, SIGSEGV);
88 DEFINE(SEGV_MAPERR, SEGV_MAPERR); 93 DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
89 DEFINE(SIGTRAP, SIGTRAP); 94 DEFINE(LSIGTRAP, SIGTRAP);
90 DEFINE(TRAP_TRACE, TRAP_TRACE); 95 DEFINE(LTRAP_TRACE, TRAP_TRACE);
91 96
92 /* offsets into the custom struct */ 97 /* offsets into the custom struct */
93 DEFINE(CUSTOMBASE, &amiga_custom); 98 DEFINE(CUSTOMBASE, &amiga_custom);
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index c3735cd6207e..922f52e7ed1a 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -77,17 +77,17 @@ ENTRY(ret_from_fork)
77 jra .Lret_from_exception 77 jra .Lret_from_exception
78 78
79do_trace_entry: 79do_trace_entry:
80 movel #-ENOSYS,%sp@(PT_D0) | needed for strace 80 movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace
81 subql #4,%sp 81 subql #4,%sp
82 SAVE_SWITCH_STACK 82 SAVE_SWITCH_STACK
83 jbsr syscall_trace 83 jbsr syscall_trace
84 RESTORE_SWITCH_STACK 84 RESTORE_SWITCH_STACK
85 addql #4,%sp 85 addql #4,%sp
86 movel %sp@(PT_ORIG_D0),%d0 86 movel %sp@(PT_OFF_ORIG_D0),%d0
87 cmpl #NR_syscalls,%d0 87 cmpl #NR_syscalls,%d0
88 jcs syscall 88 jcs syscall
89badsys: 89badsys:
90 movel #-ENOSYS,%sp@(PT_D0) 90 movel #-ENOSYS,%sp@(PT_OFF_D0)
91 jra ret_from_syscall 91 jra ret_from_syscall
92 92
93do_trace_exit: 93do_trace_exit:
@@ -103,7 +103,7 @@ ENTRY(ret_from_signal)
103 addql #4,%sp 103 addql #4,%sp
104/* on 68040 complete pending writebacks if any */ 104/* on 68040 complete pending writebacks if any */
105#ifdef CONFIG_M68040 105#ifdef CONFIG_M68040
106 bfextu %sp@(PT_VECTOR){#0,#4},%d0 106 bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0
107 subql #7,%d0 | bus error frame ? 107 subql #7,%d0 | bus error frame ?
108 jbne 1f 108 jbne 1f
109 movel %sp,%sp@- 109 movel %sp,%sp@-
@@ -127,7 +127,7 @@ ENTRY(system_call)
127 jcc badsys 127 jcc badsys
128syscall: 128syscall:
129 jbsr @(sys_call_table,%d0:l:4)@(0) 129 jbsr @(sys_call_table,%d0:l:4)@(0)
130 movel %d0,%sp@(PT_D0) | save the return value 130 movel %d0,%sp@(PT_OFF_D0) | save the return value
131ret_from_syscall: 131ret_from_syscall:
132 |oriw #0x0700,%sr 132 |oriw #0x0700,%sr
133 movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 133 movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
@@ -135,7 +135,7 @@ ret_from_syscall:
1351: RESTORE_ALL 1351: RESTORE_ALL
136 136
137syscall_exit_work: 137syscall_exit_work:
138 btst #5,%sp@(PT_SR) | check if returning to kernel 138 btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
139 bnes 1b | if so, skip resched, signals 139 bnes 1b | if so, skip resched, signals
140 lslw #1,%d0 140 lslw #1,%d0
141 jcs do_trace_exit 141 jcs do_trace_exit
@@ -148,7 +148,7 @@ syscall_exit_work:
148 148
149ENTRY(ret_from_exception) 149ENTRY(ret_from_exception)
150.Lret_from_exception: 150.Lret_from_exception:
151 btst #5,%sp@(PT_SR) | check if returning to kernel 151 btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
152 bnes 1f | if so, skip resched, signals 152 bnes 1f | if so, skip resched, signals
153 | only allow interrupts when we are really the last one on the 153 | only allow interrupts when we are really the last one on the
154 | kernel stack, otherwise stack overflow can occur during 154 | kernel stack, otherwise stack overflow can occur during
@@ -182,7 +182,7 @@ do_signal_return:
182 jbra resume_userspace 182 jbra resume_userspace
183 183
184do_delayed_trace: 184do_delayed_trace:
185 bclr #7,%sp@(PT_SR) | clear trace bit in SR 185 bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR
186 pea 1 | send SIGTRAP 186 pea 1 | send SIGTRAP
187 movel %curptr,%sp@- 187 movel %curptr,%sp@-
188 pea LSIGTRAP 188 pea LSIGTRAP
@@ -199,7 +199,7 @@ ENTRY(auto_inthandler)
199 GET_CURRENT(%d0) 199 GET_CURRENT(%d0)
200 addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 200 addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
201 | put exception # in d0 201 | put exception # in d0
202 bfextu %sp@(PT_VECTOR){#4,#10},%d0 202 bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
203 subw #VEC_SPUR,%d0 203 subw #VEC_SPUR,%d0
204 204
205 movel %sp,%sp@- 205 movel %sp,%sp@-
@@ -216,7 +216,7 @@ ret_from_interrupt:
216 ALIGN 216 ALIGN
217ret_from_last_interrupt: 217ret_from_last_interrupt:
218 moveq #(~ALLOWINT>>8)&0xff,%d0 218 moveq #(~ALLOWINT>>8)&0xff,%d0
219 andb %sp@(PT_SR),%d0 219 andb %sp@(PT_OFF_SR),%d0
220 jne 2b 220 jne 2b
221 221
222 /* check if we need to do software interrupts */ 222 /* check if we need to do software interrupts */
@@ -232,7 +232,7 @@ ENTRY(user_inthandler)
232 GET_CURRENT(%d0) 232 GET_CURRENT(%d0)
233 addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 233 addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
234 | put exception # in d0 234 | put exception # in d0
235 bfextu %sp@(PT_VECTOR){#4,#10},%d0 235 bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
236user_irqvec_fixup = . + 2 236user_irqvec_fixup = . + 2
237 subw #VEC_USER,%d0 237 subw #VEC_USER,%d0
238 238
diff --git a/arch/m68k/math-emu/fp_entry.S b/arch/m68k/math-emu/fp_entry.S
index 954b4f304a7d..a3fe1f348dfe 100644
--- a/arch/m68k/math-emu/fp_entry.S
+++ b/arch/m68k/math-emu/fp_entry.S
@@ -85,8 +85,8 @@ fp_err_ua2:
85fp_err_ua1: 85fp_err_ua1:
86 addq.l #4,%sp 86 addq.l #4,%sp
87 move.l %a0,-(%sp) 87 move.l %a0,-(%sp)
88 pea SEGV_MAPERR 88 pea LSEGV_MAPERR
89 pea SIGSEGV 89 pea LSIGSEGV
90 jsr fpemu_signal 90 jsr fpemu_signal
91 add.w #12,%sp 91 add.w #12,%sp
92 jra ret_from_exception 92 jra ret_from_exception
@@ -96,8 +96,8 @@ fp_err_ua1:
96 | it does not really belong here, but... 96 | it does not really belong here, but...
97fp_sendtrace060: 97fp_sendtrace060:
98 move.l (FPS_PC,%sp),-(%sp) 98 move.l (FPS_PC,%sp),-(%sp)
99 pea TRAP_TRACE 99 pea LTRAP_TRACE
100 pea SIGTRAP 100 pea LSIGTRAP
101 jsr fpemu_signal 101 jsr fpemu_signal
102 add.w #12,%sp 102 add.w #12,%sp
103 jra ret_from_exception 103 jra ret_from_exception
@@ -122,17 +122,17 @@ fp_get_data_reg:
122 .long fp_get_d6, fp_get_d7 122 .long fp_get_d6, fp_get_d7
123 123
124fp_get_d0: 124fp_get_d0:
125 move.l (PT_D0+8,%sp),%d0 125 move.l (PT_OFF_D0+8,%sp),%d0
126 printf PREGISTER,"{d0->%08x}",1,%d0 126 printf PREGISTER,"{d0->%08x}",1,%d0
127 rts 127 rts
128 128
129fp_get_d1: 129fp_get_d1:
130 move.l (PT_D1+8,%sp),%d0 130 move.l (PT_OFF_D1+8,%sp),%d0
131 printf PREGISTER,"{d1->%08x}",1,%d0 131 printf PREGISTER,"{d1->%08x}",1,%d0
132 rts 132 rts
133 133
134fp_get_d2: 134fp_get_d2:
135 move.l (PT_D2+8,%sp),%d0 135 move.l (PT_OFF_D2+8,%sp),%d0
136 printf PREGISTER,"{d2->%08x}",1,%d0 136 printf PREGISTER,"{d2->%08x}",1,%d0
137 rts 137 rts
138 138
@@ -173,35 +173,35 @@ fp_put_data_reg:
173 173
174fp_put_d0: 174fp_put_d0:
175 printf PREGISTER,"{d0<-%08x}",1,%d0 175 printf PREGISTER,"{d0<-%08x}",1,%d0
176 move.l %d0,(PT_D0+8,%sp) 176 move.l %d0,(PT_OFF_D0+8,%sp)
177 rts 177 rts
178 178
179fp_put_d1: 179fp_put_d1:
180 printf PREGISTER,"{d1<-%08x}",1,%d0 180 printf PREGISTER,"{d1<-%08x}",1,%d0
181 move.l %d0,(PT_D1+8,%sp) 181 move.l %d0,(PT_OFF_D1+8,%sp)
182 rts 182 rts
183 183
184fp_put_d2: 184fp_put_d2:
185 printf PREGISTER,"{d2<-%08x}",1,%d0 185 printf PREGISTER,"{d2<-%08x}",1,%d0
186 move.l %d0,(PT_D2+8,%sp) 186 move.l %d0,(PT_OFF_D2+8,%sp)
187 rts 187 rts
188 188
189fp_put_d3: 189fp_put_d3:
190 printf PREGISTER,"{d3<-%08x}",1,%d0 190 printf PREGISTER,"{d3<-%08x}",1,%d0
191| move.l %d0,%d3 191| move.l %d0,%d3
192 move.l %d0,(PT_D3+8,%sp) 192 move.l %d0,(PT_OFF_D3+8,%sp)
193 rts 193 rts
194 194
195fp_put_d4: 195fp_put_d4:
196 printf PREGISTER,"{d4<-%08x}",1,%d0 196 printf PREGISTER,"{d4<-%08x}",1,%d0
197| move.l %d0,%d4 197| move.l %d0,%d4
198 move.l %d0,(PT_D4+8,%sp) 198 move.l %d0,(PT_OFF_D4+8,%sp)
199 rts 199 rts
200 200
201fp_put_d5: 201fp_put_d5:
202 printf PREGISTER,"{d5<-%08x}",1,%d0 202 printf PREGISTER,"{d5<-%08x}",1,%d0
203| move.l %d0,%d5 203| move.l %d0,%d5
204 move.l %d0,(PT_D5+8,%sp) 204 move.l %d0,(PT_OFF_D5+8,%sp)
205 rts 205 rts
206 206
207fp_put_d6: 207fp_put_d6:
@@ -225,17 +225,17 @@ fp_get_addr_reg:
225 .long fp_get_a6, fp_get_a7 225 .long fp_get_a6, fp_get_a7
226 226
227fp_get_a0: 227fp_get_a0:
228 move.l (PT_A0+8,%sp),%a0 228 move.l (PT_OFF_A0+8,%sp),%a0
229 printf PREGISTER,"{a0->%08x}",1,%a0 229 printf PREGISTER,"{a0->%08x}",1,%a0
230 rts 230 rts
231 231
232fp_get_a1: 232fp_get_a1:
233 move.l (PT_A1+8,%sp),%a0 233 move.l (PT_OFF_A1+8,%sp),%a0
234 printf PREGISTER,"{a1->%08x}",1,%a0 234 printf PREGISTER,"{a1->%08x}",1,%a0
235 rts 235 rts
236 236
237fp_get_a2: 237fp_get_a2:
238 move.l (PT_A2+8,%sp),%a0 238 move.l (PT_OFF_A2+8,%sp),%a0
239 printf PREGISTER,"{a2->%08x}",1,%a0 239 printf PREGISTER,"{a2->%08x}",1,%a0
240 rts 240 rts
241 241
@@ -276,17 +276,17 @@ fp_put_addr_reg:
276 276
277fp_put_a0: 277fp_put_a0:
278 printf PREGISTER,"{a0<-%08x}",1,%a0 278 printf PREGISTER,"{a0<-%08x}",1,%a0
279 move.l %a0,(PT_A0+8,%sp) 279 move.l %a0,(PT_OFF_A0+8,%sp)
280 rts 280 rts
281 281
282fp_put_a1: 282fp_put_a1:
283 printf PREGISTER,"{a1<-%08x}",1,%a0 283 printf PREGISTER,"{a1<-%08x}",1,%a0
284 move.l %a0,(PT_A1+8,%sp) 284 move.l %a0,(PT_OFF_A1+8,%sp)
285 rts 285 rts
286 286
287fp_put_a2: 287fp_put_a2:
288 printf PREGISTER,"{a2<-%08x}",1,%a0 288 printf PREGISTER,"{a2<-%08x}",1,%a0
289 move.l %a0,(PT_A2+8,%sp) 289 move.l %a0,(PT_OFF_A2+8,%sp)
290 rts 290 rts
291 291
292fp_put_a3: 292fp_put_a3:
diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h
index c042830793ed..30286db27c1c 100644
--- a/arch/microblaze/include/asm/device.h
+++ b/arch/microblaze/include/asm/device.h
@@ -16,6 +16,9 @@ struct dev_archdata {
16 struct device_node *of_node; 16 struct device_node *of_node;
17}; 17};
18 18
19struct pdev_archdata {
20};
21
19#endif /* _ASM_MICROBLAZE_DEVICE_H */ 22#endif /* _ASM_MICROBLAZE_DEVICE_H */
20 23
21 24
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 2ecab6155932..cf50fa29b198 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -32,6 +32,8 @@
32#include <linux/leds.h> 32#include <linux/leds.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
35#include <linux/phy.h>
36#include <linux/phy_fixed.h>
35 37
36#include <asm/addrspace.h> 38#include <asm/addrspace.h>
37#include <asm/mach-ar7/ar7.h> 39#include <asm/mach-ar7/ar7.h>
@@ -208,6 +210,12 @@ static struct physmap_flash_data physmap_flash_data = {
208 .width = 2, 210 .width = 2,
209}; 211};
210 212
213static struct fixed_phy_status fixed_phy_status __initdata = {
214 .link = 1,
215 .speed = 100,
216 .duplex = 1,
217};
218
211static struct plat_cpmac_data cpmac_low_data = { 219static struct plat_cpmac_data cpmac_low_data = {
212 .reset_bit = 17, 220 .reset_bit = 17,
213 .power_bit = 20, 221 .power_bit = 20,
@@ -530,6 +538,9 @@ static int __init ar7_register_devices(void)
530 } 538 }
531 539
532 if (ar7_has_high_cpmac()) { 540 if (ar7_has_high_cpmac()) {
541 res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
542 if (res && res != -ENODEV)
543 return res;
533 cpmac_get_mac(1, cpmac_high_data.dev_addr); 544 cpmac_get_mac(1, cpmac_high_data.dev_addr);
534 res = platform_device_register(&cpmac_high); 545 res = platform_device_register(&cpmac_high);
535 if (res) 546 if (res)
@@ -538,6 +549,10 @@ static int __init ar7_register_devices(void)
538 cpmac_low_data.phy_mask = 0xffffffff; 549 cpmac_low_data.phy_mask = 0xffffffff;
539 } 550 }
540 551
552 res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
553 if (res && res != -ENODEV)
554 return res;
555
541 cpmac_get_mac(0, cpmac_low_data.dev_addr); 556 cpmac_get_mac(0, cpmac_low_data.dev_addr);
542 res = platform_device_register(&cpmac_low); 557 res = platform_device_register(&cpmac_low);
543 if (res) 558 if (res)
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index 2abca1780169..ae05accd9fe4 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -42,6 +42,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
42#define SO_SNDTIMEO 0x1005 /* send timeout */ 42#define SO_SNDTIMEO 0x1005 /* send timeout */
43#define SO_RCVTIMEO 0x1006 /* receive timeout */ 43#define SO_RCVTIMEO 0x1006 /* receive timeout */
44#define SO_ACCEPTCONN 0x1009 44#define SO_ACCEPTCONN 0x1009
45#define SO_PROTOCOL 0x1028 /* protocol type */
46#define SO_DOMAIN 0x1029 /* domain/socket family */
45 47
46/* linux-specific, might as well be the same as on i386 */ 48/* linux-specific, might as well be the same as on i386 */
47#define SO_NO_CHECK 11 49#define SO_NO_CHECK 11
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index f9df720d2e40..01cc1630b66c 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -115,6 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
115#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ 115#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
116#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */ 116#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
117#define TIF_SECCOMP 4 /* secure computing */ 117#define TIF_SECCOMP 4 /* secure computing */
118#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
118#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ 119#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
119#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 120#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
120#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 121#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
@@ -139,6 +140,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
139#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 140#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
140#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 141#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
141#define _TIF_SECCOMP (1<<TIF_SECCOMP) 142#define _TIF_SECCOMP (1<<TIF_SECCOMP)
143#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
142#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 144#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
143#define _TIF_USEDFPU (1<<TIF_USEDFPU) 145#define _TIF_USEDFPU (1<<TIF_USEDFPU)
144#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 146#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index e855b118a079..1a6ae124635b 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -164,7 +164,7 @@ EXPORT(sysn32_call_table)
164 PTR sys_connect 164 PTR sys_connect
165 PTR sys_accept 165 PTR sys_accept
166 PTR sys_sendto 166 PTR sys_sendto
167 PTR sys_recvfrom 167 PTR compat_sys_recvfrom
168 PTR compat_sys_sendmsg /* 6045 */ 168 PTR compat_sys_sendmsg /* 6045 */
169 PTR compat_sys_recvmsg 169 PTR compat_sys_recvmsg
170 PTR sys_shutdown 170 PTR sys_shutdown
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 0c49f1a660be..cd31087a651f 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -378,8 +378,8 @@ sys_call_table:
378 PTR sys_getsockname 378 PTR sys_getsockname
379 PTR sys_getsockopt 379 PTR sys_getsockopt
380 PTR sys_listen 380 PTR sys_listen
381 PTR sys_recv /* 4175 */ 381 PTR compat_sys_recv /* 4175 */
382 PTR sys_recvfrom 382 PTR compat_sys_recvfrom
383 PTR compat_sys_recvmsg 383 PTR compat_sys_recvmsg
384 PTR sys_send 384 PTR sys_send
385 PTR compat_sys_sendmsg 385 PTR compat_sys_sendmsg
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 830c5ef9932b..6254041b942f 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -21,6 +21,7 @@
21#include <linux/compiler.h> 21#include <linux/compiler.h>
22#include <linux/syscalls.h> 22#include <linux/syscalls.h>
23#include <linux/uaccess.h> 23#include <linux/uaccess.h>
24#include <linux/tracehook.h>
24 25
25#include <asm/abi.h> 26#include <asm/abi.h>
26#include <asm/asm.h> 27#include <asm/asm.h>
@@ -700,4 +701,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
700 /* deal with pending signal delivery */ 701 /* deal with pending signal delivery */
701 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 702 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
702 do_signal(regs); 703 do_signal(regs);
704
705 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
706 clear_thread_flag(TIF_NOTIFY_RESUME);
707 tracehook_notify_resume(regs);
708 if (current->replacement_session_keyring)
709 key_replace_session_keyring();
710 }
703} 711}
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h
index fb5daf438ec9..4df75af29d76 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/asm/socket.h
@@ -57,4 +57,7 @@
57#define SO_TIMESTAMPING 37 57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING 58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59 59
60#define SO_PROTOCOL 38
61#define SO_DOMAIN 39
62
60#endif /* _ASM_SOCKET_H */ 63#endif /* _ASM_SOCKET_H */
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index feb2f2e810db..a21f43bc68e2 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -568,5 +568,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
568 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 568 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
569 clear_thread_flag(TIF_NOTIFY_RESUME); 569 clear_thread_flag(TIF_NOTIFY_RESUME);
570 tracehook_notify_resume(__frame); 570 tracehook_notify_resume(__frame);
571 if (current->replacement_session_keyring)
572 key_replace_session_keyring();
571 } 573 }
572} 574}
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index 885472bf7b78..960b1e5d8e16 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -24,6 +24,8 @@
24#define SO_RCVTIMEO 0x1006 24#define SO_RCVTIMEO 0x1006
25#define SO_ERROR 0x1007 25#define SO_ERROR 0x1007
26#define SO_TYPE 0x1008 26#define SO_TYPE 0x1008
27#define SO_PROTOCOL 0x1028
28#define SO_DOMAIN 0x1029
27#define SO_PEERNAME 0x2000 29#define SO_PEERNAME 0x2000
28 30
29#define SO_NO_CHECK 0x400b 31#define SO_NO_CHECK 0x400b
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 4ce0edfbe969..ac775a76bff7 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -59,6 +59,7 @@ struct thread_info {
59#define TIF_MEMDIE 5 59#define TIF_MEMDIE 5
60#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ 60#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */
61#define TIF_FREEZE 7 /* is freezing for suspend */ 61#define TIF_FREEZE 7 /* is freezing for suspend */
62#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
62 63
63#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 64#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
64#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 65#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -67,8 +68,9 @@ struct thread_info {
67#define _TIF_32BIT (1 << TIF_32BIT) 68#define _TIF_32BIT (1 << TIF_32BIT)
68#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 69#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
69#define _TIF_FREEZE (1 << TIF_FREEZE) 70#define _TIF_FREEZE (1 << TIF_FREEZE)
71#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
70 72
71#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | \ 73#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
72 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) 74 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
73 75
74#endif /* __KERNEL__ */ 76#endif /* __KERNEL__ */
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index e552e547cb93..8c4712b74dc1 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -948,7 +948,7 @@ intr_check_sig:
948 /* As above */ 948 /* As above */
949 mfctl %cr30,%r1 949 mfctl %cr30,%r1
950 LDREG TI_FLAGS(%r1),%r19 950 LDREG TI_FLAGS(%r1),%r19
951 ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20 951 ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20
952 and,COND(<>) %r19, %r20, %r0 952 and,COND(<>) %r19, %r20, %r0
953 b,n intr_restore /* skip past if we've nothing to do */ 953 b,n intr_restore /* skip past if we've nothing to do */
954 954
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index f82544225e8e..8eb3c63c407a 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -25,6 +25,7 @@
25#include <linux/stddef.h> 25#include <linux/stddef.h>
26#include <linux/compat.h> 26#include <linux/compat.h>
27#include <linux/elf.h> 27#include <linux/elf.h>
28#include <linux/tracehook.h>
28#include <asm/ucontext.h> 29#include <asm/ucontext.h>
29#include <asm/rt_sigframe.h> 30#include <asm/rt_sigframe.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -645,4 +646,11 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall)
645 if (test_thread_flag(TIF_SIGPENDING) || 646 if (test_thread_flag(TIF_SIGPENDING) ||
646 test_thread_flag(TIF_RESTORE_SIGMASK)) 647 test_thread_flag(TIF_RESTORE_SIGMASK))
647 do_signal(regs, in_syscall); 648 do_signal(regs, in_syscall);
649
650 if (test_thread_flag(TIF_NOTIFY_RESUME)) {
651 clear_thread_flag(TIF_NOTIFY_RESUME);
652 tracehook_notify_resume(regs);
653 if (current->replacement_session_keyring)
654 key_replace_session_keyring();
655 }
648} 656}
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 7d2277cef09a..e3e06e0f7fc0 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -30,4 +30,7 @@ dev_archdata_get_node(const struct dev_archdata *ad)
30 return ad->of_node; 30 return ad->of_node;
31} 31}
32 32
33struct pdev_archdata {
34};
35
33#endif /* _ASM_POWERPC_DEVICE_H */ 36#endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index b44aaabdd1a6..0c34371ec49c 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -424,6 +424,29 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
424#endif 424#endif
425} 425}
426 426
427static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
428{
429 struct dma_mapping_ops *ops = get_dma_ops(dev);
430
431 if (ops->addr_needs_map && ops->addr_needs_map(dev, addr, size))
432 return 0;
433
434 if (!dev->dma_mask)
435 return 0;
436
437 return addr + size <= *dev->dma_mask;
438}
439
440static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
441{
442 return paddr + get_dma_direct_offset(dev);
443}
444
445static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
446{
447 return daddr - get_dma_direct_offset(dev);
448}
449
427#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) 450#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
428#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 451#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
429#ifdef CONFIG_NOT_COHERENT_CACHE 452#ifdef CONFIG_NOT_COHERENT_CACHE
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index fddc3ed715fa..c9c930ed11d7 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -34,7 +34,8 @@
34#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 34#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
35 35
36/* We don't currently support large pages. */ 36/* We don't currently support large pages. */
37#define KVM_PAGES_PER_HPAGE (1UL << 31) 37#define KVM_NR_PAGE_SIZES 1
38#define KVM_PAGES_PER_HPAGE(x) (1UL<<31)
38 39
39struct kvm; 40struct kvm;
40struct kvm_run; 41struct kvm_run;
@@ -153,7 +154,6 @@ struct kvm_vcpu_arch {
153 u32 pid; 154 u32 pid;
154 u32 swap_pid; 155 u32 swap_pid;
155 156
156 u32 pvr;
157 u32 ccr0; 157 u32 ccr0;
158 u32 ccr1; 158 u32 ccr1;
159 u32 dbcr0; 159 u32 dbcr0;
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index eb17da781128..2a5da069714e 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -104,8 +104,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
104 else 104 else
105 pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); 105 pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
106 106
107#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) 107#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
108 /* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we 108 /* Second case is 32-bit with 64-bit PTE. In this case, we
109 * can just store as long as we do the two halves in the right order 109 * can just store as long as we do the two halves in the right order
110 * with a barrier in between. This is possible because we take care, 110 * with a barrier in between. This is possible because we take care,
111 * in the hash code, to pre-invalidate if the PTE was already hashed, 111 * in the hash code, to pre-invalidate if the PTE was already hashed,
@@ -140,7 +140,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
140 140
141#else 141#else
142 /* Anything else just stores the PTE normally. That covers all 64-bit 142 /* Anything else just stores the PTE normally. That covers all 64-bit
143 * cases, and 32-bit non-hash with 64-bit PTEs in UP mode 143 * cases, and 32-bit non-hash with 32-bit PTEs.
144 */ 144 */
145 *ptep = pte; 145 *ptep = pte;
146#endif 146#endif
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index 157c5ca581c8..f388f0ab193f 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -154,6 +154,7 @@ int qe_get_snum(void);
154void qe_put_snum(u8 snum); 154void qe_put_snum(u8 snum);
155unsigned int qe_get_num_of_risc(void); 155unsigned int qe_get_num_of_risc(void);
156unsigned int qe_get_num_of_snums(void); 156unsigned int qe_get_num_of_snums(void);
157int qe_alive_during_sleep(void);
157 158
158/* we actually use cpm_muram implementation, define this for convenience */ 159/* we actually use cpm_muram implementation, define this for convenience */
159#define qe_muram_init cpm_muram_init 160#define qe_muram_init cpm_muram_init
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index 1e5cfad0e3f7..3ab8b3e6feb0 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -64,4 +64,7 @@
64#define SO_TIMESTAMPING 37 64#define SO_TIMESTAMPING 37
65#define SCM_TIMESTAMPING SO_TIMESTAMPING 65#define SCM_TIMESTAMPING SO_TIMESTAMPING
66 66
67#define SO_PROTOCOL 38
68#define SO_DOMAIN 39
69
67#endif /* _ASM_POWERPC_SOCKET_H */ 70#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
index c3b193121f81..198266cf9e2d 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -54,7 +54,7 @@
54 * This returns the old value in the lock, so we succeeded 54 * This returns the old value in the lock, so we succeeded
55 * in getting the lock if the return value is 0. 55 * in getting the lock if the return value is 0.
56 */ 56 */
57static inline unsigned long __spin_trylock(raw_spinlock_t *lock) 57static inline unsigned long arch_spin_trylock(raw_spinlock_t *lock)
58{ 58{
59 unsigned long tmp, token; 59 unsigned long tmp, token;
60 60
@@ -76,7 +76,7 @@ static inline unsigned long __spin_trylock(raw_spinlock_t *lock)
76static inline int __raw_spin_trylock(raw_spinlock_t *lock) 76static inline int __raw_spin_trylock(raw_spinlock_t *lock)
77{ 77{
78 CLEAR_IO_SYNC; 78 CLEAR_IO_SYNC;
79 return __spin_trylock(lock) == 0; 79 return arch_spin_trylock(lock) == 0;
80} 80}
81 81
82/* 82/*
@@ -108,7 +108,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
108{ 108{
109 CLEAR_IO_SYNC; 109 CLEAR_IO_SYNC;
110 while (1) { 110 while (1) {
111 if (likely(__spin_trylock(lock) == 0)) 111 if (likely(arch_spin_trylock(lock) == 0))
112 break; 112 break;
113 do { 113 do {
114 HMT_low(); 114 HMT_low();
@@ -126,7 +126,7 @@ void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
126 126
127 CLEAR_IO_SYNC; 127 CLEAR_IO_SYNC;
128 while (1) { 128 while (1) {
129 if (likely(__spin_trylock(lock) == 0)) 129 if (likely(arch_spin_trylock(lock) == 0))
130 break; 130 break;
131 local_save_flags(flags_dis); 131 local_save_flags(flags_dis);
132 local_irq_restore(flags); 132 local_irq_restore(flags);
@@ -181,7 +181,7 @@ extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
181 * This returns the old value in the lock + 1, 181 * This returns the old value in the lock + 1,
182 * so we got a read lock if the return value is > 0. 182 * so we got a read lock if the return value is > 0.
183 */ 183 */
184static inline long __read_trylock(raw_rwlock_t *rw) 184static inline long arch_read_trylock(raw_rwlock_t *rw)
185{ 185{
186 long tmp; 186 long tmp;
187 187
@@ -205,7 +205,7 @@ static inline long __read_trylock(raw_rwlock_t *rw)
205 * This returns the old value in the lock, 205 * This returns the old value in the lock,
206 * so we got the write lock if the return value is 0. 206 * so we got the write lock if the return value is 0.
207 */ 207 */
208static inline long __write_trylock(raw_rwlock_t *rw) 208static inline long arch_write_trylock(raw_rwlock_t *rw)
209{ 209{
210 long tmp, token; 210 long tmp, token;
211 211
@@ -228,7 +228,7 @@ static inline long __write_trylock(raw_rwlock_t *rw)
228static inline void __raw_read_lock(raw_rwlock_t *rw) 228static inline void __raw_read_lock(raw_rwlock_t *rw)
229{ 229{
230 while (1) { 230 while (1) {
231 if (likely(__read_trylock(rw) > 0)) 231 if (likely(arch_read_trylock(rw) > 0))
232 break; 232 break;
233 do { 233 do {
234 HMT_low(); 234 HMT_low();
@@ -242,7 +242,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
242static inline void __raw_write_lock(raw_rwlock_t *rw) 242static inline void __raw_write_lock(raw_rwlock_t *rw)
243{ 243{
244 while (1) { 244 while (1) {
245 if (likely(__write_trylock(rw) == 0)) 245 if (likely(arch_write_trylock(rw) == 0))
246 break; 246 break;
247 do { 247 do {
248 HMT_low(); 248 HMT_low();
@@ -255,12 +255,12 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
255 255
256static inline int __raw_read_trylock(raw_rwlock_t *rw) 256static inline int __raw_read_trylock(raw_rwlock_t *rw)
257{ 257{
258 return __read_trylock(rw) > 0; 258 return arch_read_trylock(rw) > 0;
259} 259}
260 260
261static inline int __raw_write_trylock(raw_rwlock_t *rw) 261static inline int __raw_write_trylock(raw_rwlock_t *rw)
262{ 262{
263 return __write_trylock(rw) == 0; 263 return arch_write_trylock(rw) == 0;
264} 264}
265 265
266static inline void __raw_read_unlock(raw_rwlock_t *rw) 266static inline void __raw_read_unlock(raw_rwlock_t *rw)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index b73396b93905..9619285f64e8 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -97,7 +97,7 @@ obj64-$(CONFIG_AUDIT) += compat_audit.o
97 97
98obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 98obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
99obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 99obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
100obj-$(CONFIG_PPC_PERF_CTRS) += perf_counter.o 100obj-$(CONFIG_PPC_PERF_CTRS) += perf_counter.o perf_callchain.o
101obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ 101obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
102 power5+-pmu.o power6-pmu.o power7-pmu.o 102 power5+-pmu.o power6-pmu.o power7-pmu.o
103obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o 103obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 561b64652311..197b15646eeb 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -67,6 +67,8 @@ int main(void)
67 DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id)); 67 DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id));
68#ifdef CONFIG_PPC64 68#ifdef CONFIG_PPC64
69 DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); 69 DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
70 DEFINE(SIGSEGV, SIGSEGV);
71 DEFINE(NMI_MASK, NMI_MASK);
70#else 72#else
71 DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); 73 DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
72#endif /* CONFIG_PPC64 */ 74#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index 68ccf11e4f19..e8a57de85bcf 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -24,50 +24,12 @@
24int swiotlb __read_mostly; 24int swiotlb __read_mostly;
25unsigned int ppc_swiotlb_enable; 25unsigned int ppc_swiotlb_enable;
26 26
27void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr)
28{
29 unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr));
30 void *pageaddr = page_address(pfn_to_page(pfn));
31
32 if (pageaddr != NULL)
33 return pageaddr + (addr % PAGE_SIZE);
34 return NULL;
35}
36
37dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
38{
39 return paddr + get_dma_direct_offset(hwdev);
40}
41
42phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
43
44{
45 return baddr - get_dma_direct_offset(hwdev);
46}
47
48/*
49 * Determine if an address needs bounce buffering via swiotlb.
50 * Going forward I expect the swiotlb code to generalize on using
51 * a dma_ops->addr_needs_map, and this function will move from here to the
52 * generic swiotlb code.
53 */
54int
55swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr,
56 size_t size)
57{
58 struct dma_mapping_ops *dma_ops = get_dma_ops(hwdev);
59
60 BUG_ON(!dma_ops);
61 return dma_ops->addr_needs_map(hwdev, addr, size);
62}
63
64/* 27/*
65 * Determine if an address is reachable by a pci device, or if we must bounce. 28 * Determine if an address is reachable by a pci device, or if we must bounce.
66 */ 29 */
67static int 30static int
68swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) 31swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
69{ 32{
70 u64 mask = dma_get_mask(hwdev);
71 dma_addr_t max; 33 dma_addr_t max;
72 struct pci_controller *hose; 34 struct pci_controller *hose;
73 struct pci_dev *pdev = to_pci_dev(hwdev); 35 struct pci_dev *pdev = to_pci_dev(hwdev);
@@ -79,16 +41,9 @@ swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
79 if ((addr + size > max) | (addr < hose->dma_window_base_cur)) 41 if ((addr + size > max) | (addr < hose->dma_window_base_cur))
80 return 1; 42 return 1;
81 43
82 return !is_buffer_dma_capable(mask, addr, size); 44 return 0;
83}
84
85static int
86swiotlb_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
87{
88 return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
89} 45}
90 46
91
92/* 47/*
93 * At the moment, all platforms that use this code only require 48 * At the moment, all platforms that use this code only require
94 * swiotlb to be used if we're operating on HIGHMEM. Since 49 * swiotlb to be used if we're operating on HIGHMEM. Since
@@ -104,7 +59,6 @@ struct dma_mapping_ops swiotlb_dma_ops = {
104 .dma_supported = swiotlb_dma_supported, 59 .dma_supported = swiotlb_dma_supported,
105 .map_page = swiotlb_map_page, 60 .map_page = swiotlb_map_page,
106 .unmap_page = swiotlb_unmap_page, 61 .unmap_page = swiotlb_unmap_page,
107 .addr_needs_map = swiotlb_addr_needs_map,
108 .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, 62 .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
109 .sync_single_range_for_device = swiotlb_sync_single_range_for_device, 63 .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
110 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, 64 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index eb898112e577..8ac85e08ffae 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -729,6 +729,11 @@ BEGIN_FTR_SECTION
729 bne- do_ste_alloc /* If so handle it */ 729 bne- do_ste_alloc /* If so handle it */
730END_FTR_SECTION_IFCLR(CPU_FTR_SLB) 730END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
731 731
732 clrrdi r11,r1,THREAD_SHIFT
733 lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */
734 andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */
735 bne 77f /* then don't call hash_page now */
736
732 /* 737 /*
733 * On iSeries, we soft-disable interrupts here, then 738 * On iSeries, we soft-disable interrupts here, then
734 * hard-enable interrupts so that the hash_page code can spin on 739 * hard-enable interrupts so that the hash_page code can spin on
@@ -833,6 +838,20 @@ handle_page_fault:
833 bl .low_hash_fault 838 bl .low_hash_fault
834 b .ret_from_except 839 b .ret_from_except
835 840
841/*
842 * We come here as a result of a DSI at a point where we don't want
843 * to call hash_page, such as when we are accessing memory (possibly
844 * user memory) inside a PMU interrupt that occurred while interrupts
845 * were soft-disabled. We want to invoke the exception handler for
846 * the access, or panic if there isn't a handler.
847 */
84877: bl .save_nvgprs
849 mr r4,r3
850 addi r3,r1,STACK_FRAME_OVERHEAD
851 li r5,SIGSEGV
852 bl .bad_page_fault
853 b .ret_from_except
854
836 /* here we have a segment miss */ 855 /* here we have a segment miss */
837do_ste_alloc: 856do_ste_alloc:
838 bl .ste_allocate /* try to insert stab entry */ 857 bl .ste_allocate /* try to insert stab entry */
diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c
new file mode 100644
index 000000000000..f74b62c67511
--- /dev/null
+++ b/arch/powerpc/kernel/perf_callchain.c
@@ -0,0 +1,527 @@
1/*
2 * Performance counter callchain support - powerpc architecture code
3 *
4 * Copyright © 2009 Paul Mackerras, IBM Corporation.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/kernel.h>
12#include <linux/sched.h>
13#include <linux/perf_counter.h>
14#include <linux/percpu.h>
15#include <linux/uaccess.h>
16#include <linux/mm.h>
17#include <asm/ptrace.h>
18#include <asm/pgtable.h>
19#include <asm/sigcontext.h>
20#include <asm/ucontext.h>
21#include <asm/vdso.h>
22#ifdef CONFIG_PPC64
23#include "ppc32.h"
24#endif
25
26/*
27 * Store another value in a callchain_entry.
28 */
29static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip)
30{
31 unsigned int nr = entry->nr;
32
33 if (nr < PERF_MAX_STACK_DEPTH) {
34 entry->ip[nr] = ip;
35 entry->nr = nr + 1;
36 }
37}
38
39/*
40 * Is sp valid as the address of the next kernel stack frame after prev_sp?
41 * The next frame may be in a different stack area but should not go
42 * back down in the same stack area.
43 */
44static int valid_next_sp(unsigned long sp, unsigned long prev_sp)
45{
46 if (sp & 0xf)
47 return 0; /* must be 16-byte aligned */
48 if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
49 return 0;
50 if (sp >= prev_sp + STACK_FRAME_OVERHEAD)
51 return 1;
52 /*
53 * sp could decrease when we jump off an interrupt stack
54 * back to the regular process stack.
55 */
56 if ((sp & ~(THREAD_SIZE - 1)) != (prev_sp & ~(THREAD_SIZE - 1)))
57 return 1;
58 return 0;
59}
60
61static void perf_callchain_kernel(struct pt_regs *regs,
62 struct perf_callchain_entry *entry)
63{
64 unsigned long sp, next_sp;
65 unsigned long next_ip;
66 unsigned long lr;
67 long level = 0;
68 unsigned long *fp;
69
70 lr = regs->link;
71 sp = regs->gpr[1];
72 callchain_store(entry, PERF_CONTEXT_KERNEL);
73 callchain_store(entry, regs->nip);
74
75 if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
76 return;
77
78 for (;;) {
79 fp = (unsigned long *) sp;
80 next_sp = fp[0];
81
82 if (next_sp == sp + STACK_INT_FRAME_SIZE &&
83 fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
84 /*
85 * This looks like an interrupt frame for an
86 * interrupt that occurred in the kernel
87 */
88 regs = (struct pt_regs *)(sp + STACK_FRAME_OVERHEAD);
89 next_ip = regs->nip;
90 lr = regs->link;
91 level = 0;
92 callchain_store(entry, PERF_CONTEXT_KERNEL);
93
94 } else {
95 if (level == 0)
96 next_ip = lr;
97 else
98 next_ip = fp[STACK_FRAME_LR_SAVE];
99
100 /*
101 * We can't tell which of the first two addresses
102 * we get are valid, but we can filter out the
103 * obviously bogus ones here. We replace them
104 * with 0 rather than removing them entirely so
105 * that userspace can tell which is which.
106 */
107 if ((level == 1 && next_ip == lr) ||
108 (level <= 1 && !kernel_text_address(next_ip)))
109 next_ip = 0;
110
111 ++level;
112 }
113
114 callchain_store(entry, next_ip);
115 if (!valid_next_sp(next_sp, sp))
116 return;
117 sp = next_sp;
118 }
119}
120
121#ifdef CONFIG_PPC64
122
123#ifdef CONFIG_HUGETLB_PAGE
124#define is_huge_psize(pagesize) (HPAGE_SHIFT && mmu_huge_psizes[pagesize])
125#else
126#define is_huge_psize(pagesize) 0
127#endif
128
129/*
130 * On 64-bit we don't want to invoke hash_page on user addresses from
131 * interrupt context, so if the access faults, we read the page tables
132 * to find which page (if any) is mapped and access it directly.
133 */
134static int read_user_stack_slow(void __user *ptr, void *ret, int nb)
135{
136 pgd_t *pgdir;
137 pte_t *ptep, pte;
138 int pagesize;
139 unsigned long addr = (unsigned long) ptr;
140 unsigned long offset;
141 unsigned long pfn;
142 void *kaddr;
143
144 pgdir = current->mm->pgd;
145 if (!pgdir)
146 return -EFAULT;
147
148 pagesize = get_slice_psize(current->mm, addr);
149
150 /* align address to page boundary */
151 offset = addr & ((1ul << mmu_psize_defs[pagesize].shift) - 1);
152 addr -= offset;
153
154 if (is_huge_psize(pagesize))
155 ptep = huge_pte_offset(current->mm, addr);
156 else
157 ptep = find_linux_pte(pgdir, addr);
158
159 if (ptep == NULL)
160 return -EFAULT;
161 pte = *ptep;
162 if (!pte_present(pte) || !(pte_val(pte) & _PAGE_USER))
163 return -EFAULT;
164 pfn = pte_pfn(pte);
165 if (!page_is_ram(pfn))
166 return -EFAULT;
167
168 /* no highmem to worry about here */
169 kaddr = pfn_to_kaddr(pfn);
170 memcpy(ret, kaddr + offset, nb);
171 return 0;
172}
173
174static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
175{
176 if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
177 ((unsigned long)ptr & 7))
178 return -EFAULT;
179
180 if (!__get_user_inatomic(*ret, ptr))
181 return 0;
182
183 return read_user_stack_slow(ptr, ret, 8);
184}
185
186static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
187{
188 if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
189 ((unsigned long)ptr & 3))
190 return -EFAULT;
191
192 if (!__get_user_inatomic(*ret, ptr))
193 return 0;
194
195 return read_user_stack_slow(ptr, ret, 4);
196}
197
198static inline int valid_user_sp(unsigned long sp, int is_64)
199{
200 if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
201 return 0;
202 return 1;
203}
204
205/*
206 * 64-bit user processes use the same stack frame for RT and non-RT signals.
207 */
208struct signal_frame_64 {
209 char dummy[__SIGNAL_FRAMESIZE];
210 struct ucontext uc;
211 unsigned long unused[2];
212 unsigned int tramp[6];
213 struct siginfo *pinfo;
214 void *puc;
215 struct siginfo info;
216 char abigap[288];
217};
218
219static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
220{
221 if (nip == fp + offsetof(struct signal_frame_64, tramp))
222 return 1;
223 if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
224 nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
225 return 1;
226 return 0;
227}
228
229/*
230 * Do some sanity checking on the signal frame pointed to by sp.
231 * We check the pinfo and puc pointers in the frame.
232 */
233static int sane_signal_64_frame(unsigned long sp)
234{
235 struct signal_frame_64 __user *sf;
236 unsigned long pinfo, puc;
237
238 sf = (struct signal_frame_64 __user *) sp;
239 if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) ||
240 read_user_stack_64((unsigned long __user *) &sf->puc, &puc))
241 return 0;
242 return pinfo == (unsigned long) &sf->info &&
243 puc == (unsigned long) &sf->uc;
244}
245
246static void perf_callchain_user_64(struct pt_regs *regs,
247 struct perf_callchain_entry *entry)
248{
249 unsigned long sp, next_sp;
250 unsigned long next_ip;
251 unsigned long lr;
252 long level = 0;
253 struct signal_frame_64 __user *sigframe;
254 unsigned long __user *fp, *uregs;
255
256 next_ip = regs->nip;
257 lr = regs->link;
258 sp = regs->gpr[1];
259 callchain_store(entry, PERF_CONTEXT_USER);
260 callchain_store(entry, next_ip);
261
262 for (;;) {
263 fp = (unsigned long __user *) sp;
264 if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
265 return;
266 if (level > 0 && read_user_stack_64(&fp[2], &next_ip))
267 return;
268
269 /*
270 * Note: the next_sp - sp >= signal frame size check
271 * is true when next_sp < sp, which can happen when
272 * transitioning from an alternate signal stack to the
273 * normal stack.
274 */
275 if (next_sp - sp >= sizeof(struct signal_frame_64) &&
276 (is_sigreturn_64_address(next_ip, sp) ||
277 (level <= 1 && is_sigreturn_64_address(lr, sp))) &&
278 sane_signal_64_frame(sp)) {
279 /*
280 * This looks like an signal frame
281 */
282 sigframe = (struct signal_frame_64 __user *) sp;
283 uregs = sigframe->uc.uc_mcontext.gp_regs;
284 if (read_user_stack_64(&uregs[PT_NIP], &next_ip) ||
285 read_user_stack_64(&uregs[PT_LNK], &lr) ||
286 read_user_stack_64(&uregs[PT_R1], &sp))
287 return;
288 level = 0;
289 callchain_store(entry, PERF_CONTEXT_USER);
290 callchain_store(entry, next_ip);
291 continue;
292 }
293
294 if (level == 0)
295 next_ip = lr;
296 callchain_store(entry, next_ip);
297 ++level;
298 sp = next_sp;
299 }
300}
301
302static inline int current_is_64bit(void)
303{
304 /*
305 * We can't use test_thread_flag() here because we may be on an
306 * interrupt stack, and the thread flags don't get copied over
307 * from the thread_info on the main stack to the interrupt stack.
308 */
309 return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
310}
311
312#else /* CONFIG_PPC64 */
313/*
314 * On 32-bit we just access the address and let hash_page create a
315 * HPTE if necessary, so there is no need to fall back to reading
316 * the page tables. Since this is called at interrupt level,
317 * do_page_fault() won't treat a DSI as a page fault.
318 */
319static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
320{
321 if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
322 ((unsigned long)ptr & 3))
323 return -EFAULT;
324
325 return __get_user_inatomic(*ret, ptr);
326}
327
328static inline void perf_callchain_user_64(struct pt_regs *regs,
329 struct perf_callchain_entry *entry)
330{
331}
332
333static inline int current_is_64bit(void)
334{
335 return 0;
336}
337
338static inline int valid_user_sp(unsigned long sp, int is_64)
339{
340 if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
341 return 0;
342 return 1;
343}
344
345#define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
346#define sigcontext32 sigcontext
347#define mcontext32 mcontext
348#define ucontext32 ucontext
349#define compat_siginfo_t struct siginfo
350
351#endif /* CONFIG_PPC64 */
352
353/*
354 * Layout for non-RT signal frames
355 */
356struct signal_frame_32 {
357 char dummy[__SIGNAL_FRAMESIZE32];
358 struct sigcontext32 sctx;
359 struct mcontext32 mctx;
360 int abigap[56];
361};
362
363/*
364 * Layout for RT signal frames
365 */
366struct rt_signal_frame_32 {
367 char dummy[__SIGNAL_FRAMESIZE32 + 16];
368 compat_siginfo_t info;
369 struct ucontext32 uc;
370 int abigap[56];
371};
372
373static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
374{
375 if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
376 return 1;
377 if (vdso32_sigtramp && current->mm->context.vdso_base &&
378 nip == current->mm->context.vdso_base + vdso32_sigtramp)
379 return 1;
380 return 0;
381}
382
383static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
384{
385 if (nip == fp + offsetof(struct rt_signal_frame_32,
386 uc.uc_mcontext.mc_pad))
387 return 1;
388 if (vdso32_rt_sigtramp && current->mm->context.vdso_base &&
389 nip == current->mm->context.vdso_base + vdso32_rt_sigtramp)
390 return 1;
391 return 0;
392}
393
394static int sane_signal_32_frame(unsigned int sp)
395{
396 struct signal_frame_32 __user *sf;
397 unsigned int regs;
398
399 sf = (struct signal_frame_32 __user *) (unsigned long) sp;
400 if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, &regs))
401 return 0;
402 return regs == (unsigned long) &sf->mctx;
403}
404
405static int sane_rt_signal_32_frame(unsigned int sp)
406{
407 struct rt_signal_frame_32 __user *sf;
408 unsigned int regs;
409
410 sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
411 if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, &regs))
412 return 0;
413 return regs == (unsigned long) &sf->uc.uc_mcontext;
414}
415
416static unsigned int __user *signal_frame_32_regs(unsigned int sp,
417 unsigned int next_sp, unsigned int next_ip)
418{
419 struct mcontext32 __user *mctx = NULL;
420 struct signal_frame_32 __user *sf;
421 struct rt_signal_frame_32 __user *rt_sf;
422
423 /*
424 * Note: the next_sp - sp >= signal frame size check
425 * is true when next_sp < sp, for example, when
426 * transitioning from an alternate signal stack to the
427 * normal stack.
428 */
429 if (next_sp - sp >= sizeof(struct signal_frame_32) &&
430 is_sigreturn_32_address(next_ip, sp) &&
431 sane_signal_32_frame(sp)) {
432 sf = (struct signal_frame_32 __user *) (unsigned long) sp;
433 mctx = &sf->mctx;
434 }
435
436 if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
437 is_rt_sigreturn_32_address(next_ip, sp) &&
438 sane_rt_signal_32_frame(sp)) {
439 rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
440 mctx = &rt_sf->uc.uc_mcontext;
441 }
442
443 if (!mctx)
444 return NULL;
445 return mctx->mc_gregs;
446}
447
448static void perf_callchain_user_32(struct pt_regs *regs,
449 struct perf_callchain_entry *entry)
450{
451 unsigned int sp, next_sp;
452 unsigned int next_ip;
453 unsigned int lr;
454 long level = 0;
455 unsigned int __user *fp, *uregs;
456
457 next_ip = regs->nip;
458 lr = regs->link;
459 sp = regs->gpr[1];
460 callchain_store(entry, PERF_CONTEXT_USER);
461 callchain_store(entry, next_ip);
462
463 while (entry->nr < PERF_MAX_STACK_DEPTH) {
464 fp = (unsigned int __user *) (unsigned long) sp;
465 if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
466 return;
467 if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
468 return;
469
470 uregs = signal_frame_32_regs(sp, next_sp, next_ip);
471 if (!uregs && level <= 1)
472 uregs = signal_frame_32_regs(sp, next_sp, lr);
473 if (uregs) {
474 /*
475 * This looks like an signal frame, so restart
476 * the stack trace with the values in it.
477 */
478 if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
479 read_user_stack_32(&uregs[PT_LNK], &lr) ||
480 read_user_stack_32(&uregs[PT_R1], &sp))
481 return;
482 level = 0;
483 callchain_store(entry, PERF_CONTEXT_USER);
484 callchain_store(entry, next_ip);
485 continue;
486 }
487
488 if (level == 0)
489 next_ip = lr;
490 callchain_store(entry, next_ip);
491 ++level;
492 sp = next_sp;
493 }
494}
495
496/*
497 * Since we can't get PMU interrupts inside a PMU interrupt handler,
498 * we don't need separate irq and nmi entries here.
499 */
500static DEFINE_PER_CPU(struct perf_callchain_entry, callchain);
501
502struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
503{
504 struct perf_callchain_entry *entry = &__get_cpu_var(callchain);
505
506 entry->nr = 0;
507
508 if (current->pid == 0) /* idle task? */
509 return entry;
510
511 if (!user_mode(regs)) {
512 perf_callchain_kernel(regs, entry);
513 if (current->mm)
514 regs = task_pt_regs(current);
515 else
516 regs = NULL;
517 }
518
519 if (regs) {
520 if (current_is_64bit())
521 perf_callchain_user_64(regs, entry);
522 else
523 perf_callchain_user_32(regs, entry);
524 }
525
526 return entry;
527}
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 0cef809cec21..f4d1b55aa70b 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -138,7 +138,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
138 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 138 kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
139} 139}
140 140
141static int kvmppc_44x_init(void) 141static int __init kvmppc_44x_init(void)
142{ 142{
143 int r; 143 int r;
144 144
@@ -149,7 +149,7 @@ static int kvmppc_44x_init(void)
149 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE); 149 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE);
150} 150}
151 151
152static void kvmppc_44x_exit(void) 152static void __exit kvmppc_44x_exit(void)
153{ 153{
154 kvmppc_booke_exit(); 154 kvmppc_booke_exit();
155} 155}
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 4a16f472cc18..ff3cb63b8117 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -30,6 +30,7 @@
30#include "timing.h" 30#include "timing.h"
31 31
32#include "44x_tlb.h" 32#include "44x_tlb.h"
33#include "trace.h"
33 34
34#ifndef PPC44x_TLBE_SIZE 35#ifndef PPC44x_TLBE_SIZE
35#define PPC44x_TLBE_SIZE PPC44x_TLB_4K 36#define PPC44x_TLBE_SIZE PPC44x_TLB_4K
@@ -263,7 +264,7 @@ static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
263 264
264 /* XXX set tlb_44x_index to stlb_index? */ 265 /* XXX set tlb_44x_index to stlb_index? */
265 266
266 KVMTRACE_1D(STLB_INVAL, &vcpu_44x->vcpu, stlb_index, handler); 267 trace_kvm_stlb_inval(stlb_index);
267} 268}
268 269
269void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) 270void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
@@ -365,8 +366,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
365 /* Insert shadow mapping into hardware TLB. */ 366 /* Insert shadow mapping into hardware TLB. */
366 kvmppc_44x_tlbe_set_modified(vcpu_44x, victim); 367 kvmppc_44x_tlbe_set_modified(vcpu_44x, victim);
367 kvmppc_44x_tlbwe(victim, &stlbe); 368 kvmppc_44x_tlbwe(victim, &stlbe);
368 KVMTRACE_5D(STLB_WRITE, vcpu, victim, stlbe.tid, stlbe.word0, stlbe.word1, 369 trace_kvm_stlb_write(victim, stlbe.tid, stlbe.word0, stlbe.word1,
369 stlbe.word2, handler); 370 stlbe.word2);
370} 371}
371 372
372/* For a particular guest TLB entry, invalidate the corresponding host TLB 373/* For a particular guest TLB entry, invalidate the corresponding host TLB
@@ -485,8 +486,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
485 kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); 486 kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
486 } 487 }
487 488
488 KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0, 489 trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1,
489 tlbe->word1, tlbe->word2, handler); 490 tlbe->word2);
490 491
491 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); 492 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
492 return EMULATE_DONE; 493 return EMULATE_DONE;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 5a152a52796f..c29926846613 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -2,8 +2,7 @@
2# KVM configuration 2# KVM configuration
3# 3#
4 4
5config HAVE_KVM_IRQCHIP 5source "virt/kvm/Kconfig"
6 bool
7 6
8menuconfig VIRTUALIZATION 7menuconfig VIRTUALIZATION
9 bool "Virtualization" 8 bool "Virtualization"
@@ -59,17 +58,6 @@ config KVM_E500
59 58
60 If unsure, say N. 59 If unsure, say N.
61 60
62config KVM_TRACE
63 bool "KVM trace support"
64 depends on KVM && MARKERS && SYSFS
65 select RELAY
66 select DEBUG_FS
67 default n
68 ---help---
69 This option allows reading a trace of kvm-related events through
70 relayfs. Note the ABI is not considered stable and will be
71 modified in future updates.
72
73source drivers/virtio/Kconfig 61source drivers/virtio/Kconfig
74 62
75endif # VIRTUALIZATION 63endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 459c7ee580f7..37655fe19f2f 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -8,7 +8,9 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
8 8
9common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) 9common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
10 10
11common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) 11CFLAGS_44x_tlb.o := -I.
12CFLAGS_e500_tlb.o := -I.
13CFLAGS_emulate.o := -I.
12 14
13kvm-objs := $(common-objs-y) powerpc.o emulate.o 15kvm-objs := $(common-objs-y) powerpc.o emulate.o
14obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o 16obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 642e4204cf25..e7bf4d029484 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -520,7 +520,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
520 return kvmppc_core_vcpu_translate(vcpu, tr); 520 return kvmppc_core_vcpu_translate(vcpu, tr);
521} 521}
522 522
523int kvmppc_booke_init(void) 523int __init kvmppc_booke_init(void)
524{ 524{
525 unsigned long ivor[16]; 525 unsigned long ivor[16];
526 unsigned long max_ivor = 0; 526 unsigned long max_ivor = 0;
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index d8067fd81cdd..64949eef43f1 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -60,9 +60,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
60 60
61 kvmppc_e500_tlb_setup(vcpu_e500); 61 kvmppc_e500_tlb_setup(vcpu_e500);
62 62
63 /* Use the same core vertion as host's */
64 vcpu->arch.pvr = mfspr(SPRN_PVR);
65
66 return 0; 63 return 0;
67} 64}
68 65
@@ -132,7 +129,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
132 kmem_cache_free(kvm_vcpu_cache, vcpu_e500); 129 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
133} 130}
134 131
135static int kvmppc_e500_init(void) 132static int __init kvmppc_e500_init(void)
136{ 133{
137 int r, i; 134 int r, i;
138 unsigned long ivor[3]; 135 unsigned long ivor[3];
@@ -160,7 +157,7 @@ static int kvmppc_e500_init(void)
160 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); 157 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
161} 158}
162 159
163static void kvmppc_e500_exit(void) 160static void __init kvmppc_e500_exit(void)
164{ 161{
165 kvmppc_booke_exit(); 162 kvmppc_booke_exit();
166} 163}
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 3f760414b9f8..be95b8d8e3b7 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -180,6 +180,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
180 case SPRN_MMUCSR0: 180 case SPRN_MMUCSR0:
181 vcpu->arch.gpr[rt] = 0; break; 181 vcpu->arch.gpr[rt] = 0; break;
182 182
183 case SPRN_MMUCFG:
184 vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break;
185
183 /* extra exceptions */ 186 /* extra exceptions */
184 case SPRN_IVOR32: 187 case SPRN_IVOR32:
185 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; 188 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 0e773fc2d5e4..fb1e1dc11ba5 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -22,6 +22,7 @@
22 22
23#include "../mm/mmu_decl.h" 23#include "../mm/mmu_decl.h"
24#include "e500_tlb.h" 24#include "e500_tlb.h"
25#include "trace.h"
25 26
26#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1) 27#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
27 28
@@ -224,9 +225,8 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
224 225
225 kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel); 226 kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
226 stlbe->mas1 = 0; 227 stlbe->mas1 = 0;
227 KVMTRACE_5D(STLB_INVAL, &vcpu_e500->vcpu, index_of(tlbsel, esel), 228 trace_kvm_stlb_inval(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
228 stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7, 229 stlbe->mas3, stlbe->mas7);
229 handler);
230} 230}
231 231
232static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, 232static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
@@ -269,7 +269,7 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
269 tlbsel = (vcpu_e500->mas4 >> 28) & 0x1; 269 tlbsel = (vcpu_e500->mas4 >> 28) & 0x1;
270 victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0; 270 victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
271 pidsel = (vcpu_e500->mas4 >> 16) & 0xf; 271 pidsel = (vcpu_e500->mas4 >> 16) & 0xf;
272 tsized = (vcpu_e500->mas4 >> 8) & 0xf; 272 tsized = (vcpu_e500->mas4 >> 7) & 0x1f;
273 273
274 vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim) 274 vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
275 | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]); 275 | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
@@ -309,7 +309,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
309 vcpu_e500->shadow_pages[tlbsel][esel] = new_page; 309 vcpu_e500->shadow_pages[tlbsel][esel] = new_page;
310 310
311 /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */ 311 /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */
312 stlbe->mas1 = MAS1_TSIZE(BOOKE_PAGESZ_4K) 312 stlbe->mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K)
313 | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID; 313 | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID;
314 stlbe->mas2 = (gvaddr & MAS2_EPN) 314 stlbe->mas2 = (gvaddr & MAS2_EPN)
315 | e500_shadow_mas2_attrib(gtlbe->mas2, 315 | e500_shadow_mas2_attrib(gtlbe->mas2,
@@ -319,9 +319,8 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
319 vcpu_e500->vcpu.arch.msr & MSR_PR); 319 vcpu_e500->vcpu.arch.msr & MSR_PR);
320 stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN; 320 stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN;
321 321
322 KVMTRACE_5D(STLB_WRITE, &vcpu_e500->vcpu, index_of(tlbsel, esel), 322 trace_kvm_stlb_write(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
323 stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7, 323 stlbe->mas3, stlbe->mas7);
324 handler);
325} 324}
326 325
327/* XXX only map the one-one case, for now use TLB0 */ 326/* XXX only map the one-one case, for now use TLB0 */
@@ -535,9 +534,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
535 gtlbe->mas3 = vcpu_e500->mas3; 534 gtlbe->mas3 = vcpu_e500->mas3;
536 gtlbe->mas7 = vcpu_e500->mas7; 535 gtlbe->mas7 = vcpu_e500->mas7;
537 536
538 KVMTRACE_5D(GTLB_WRITE, vcpu, vcpu_e500->mas0, 537 trace_kvm_gtlb_write(vcpu_e500->mas0, gtlbe->mas1, gtlbe->mas2,
539 gtlbe->mas1, gtlbe->mas2, gtlbe->mas3, gtlbe->mas7, 538 gtlbe->mas3, gtlbe->mas7);
540 handler);
541 539
542 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ 540 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
543 if (tlbe_is_host_safe(vcpu, gtlbe)) { 541 if (tlbe_is_host_safe(vcpu, gtlbe)) {
@@ -545,7 +543,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
545 case 0: 543 case 0:
546 /* TLB0 */ 544 /* TLB0 */
547 gtlbe->mas1 &= ~MAS1_TSIZE(~0); 545 gtlbe->mas1 &= ~MAS1_TSIZE(~0);
548 gtlbe->mas1 |= MAS1_TSIZE(BOOKE_PAGESZ_4K); 546 gtlbe->mas1 |= MAS1_TSIZE(BOOK3E_PAGESZ_4K);
549 547
550 stlbsel = 0; 548 stlbsel = 0;
551 sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel); 549 sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel);
@@ -679,14 +677,14 @@ void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
679 677
680 /* Insert large initial mapping for guest. */ 678 /* Insert large initial mapping for guest. */
681 tlbe = &vcpu_e500->guest_tlb[1][0]; 679 tlbe = &vcpu_e500->guest_tlb[1][0];
682 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_256M); 680 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M);
683 tlbe->mas2 = 0; 681 tlbe->mas2 = 0;
684 tlbe->mas3 = E500_TLB_SUPER_PERM_MASK; 682 tlbe->mas3 = E500_TLB_SUPER_PERM_MASK;
685 tlbe->mas7 = 0; 683 tlbe->mas7 = 0;
686 684
687 /* 4K map for serial output. Used by kernel wrapper. */ 685 /* 4K map for serial output. Used by kernel wrapper. */
688 tlbe = &vcpu_e500->guest_tlb[1][1]; 686 tlbe = &vcpu_e500->guest_tlb[1][1];
689 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_4K); 687 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K);
690 tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G; 688 tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
691 tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK; 689 tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
692 tlbe->mas7 = 0; 690 tlbe->mas7 = 0;
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h
index 45b064b76906..d28e3010a5e2 100644
--- a/arch/powerpc/kvm/e500_tlb.h
+++ b/arch/powerpc/kvm/e500_tlb.h
@@ -16,7 +16,7 @@
16#define __KVM_E500_TLB_H__ 16#define __KVM_E500_TLB_H__
17 17
18#include <linux/kvm_host.h> 18#include <linux/kvm_host.h>
19#include <asm/mmu-fsl-booke.h> 19#include <asm/mmu-book3e.h>
20#include <asm/tlb.h> 20#include <asm/tlb.h>
21#include <asm/kvm_e500.h> 21#include <asm/kvm_e500.h>
22 22
@@ -59,7 +59,7 @@ extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
59/* TLB helper functions */ 59/* TLB helper functions */
60static inline unsigned int get_tlb_size(const struct tlbe *tlbe) 60static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
61{ 61{
62 return (tlbe->mas1 >> 8) & 0xf; 62 return (tlbe->mas1 >> 7) & 0x1f;
63} 63}
64 64
65static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe) 65static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
@@ -70,7 +70,7 @@ static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
70static inline u64 get_tlb_bytes(const struct tlbe *tlbe) 70static inline u64 get_tlb_bytes(const struct tlbe *tlbe)
71{ 71{
72 unsigned int pgsize = get_tlb_size(tlbe); 72 unsigned int pgsize = get_tlb_size(tlbe);
73 return 1ULL << 10 << (pgsize << 1); 73 return 1ULL << 10 << pgsize;
74} 74}
75 75
76static inline gva_t get_tlb_end(const struct tlbe *tlbe) 76static inline gva_t get_tlb_end(const struct tlbe *tlbe)
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index a561d6e8da1c..7737146af3fb 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -29,6 +29,7 @@
29#include <asm/kvm_ppc.h> 29#include <asm/kvm_ppc.h>
30#include <asm/disassemble.h> 30#include <asm/disassemble.h>
31#include "timing.h" 31#include "timing.h"
32#include "trace.h"
32 33
33#define OP_TRAP 3 34#define OP_TRAP 3
34 35
@@ -187,7 +188,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
187 case SPRN_SRR1: 188 case SPRN_SRR1:
188 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break; 189 vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
189 case SPRN_PVR: 190 case SPRN_PVR:
190 vcpu->arch.gpr[rt] = vcpu->arch.pvr; break; 191 vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break;
192 case SPRN_PIR:
193 vcpu->arch.gpr[rt] = mfspr(SPRN_PIR); break;
191 194
192 /* Note: mftb and TBRL/TBWL are user-accessible, so 195 /* Note: mftb and TBRL/TBWL are user-accessible, so
193 * the guest can always access the real TB anyways. 196 * the guest can always access the real TB anyways.
@@ -417,7 +420,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
417 } 420 }
418 } 421 }
419 422
420 KVMTRACE_3D(PPC_INSTR, vcpu, inst, (int)vcpu->arch.pc, emulated, entryexit); 423 trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated);
421 424
422 if (advance) 425 if (advance)
423 vcpu->arch.pc += 4; /* Advance past emulated instruction. */ 426 vcpu->arch.pc += 4; /* Advance past emulated instruction. */
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2cf915e51e7e..2a4551f78f60 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -31,25 +31,17 @@
31#include "timing.h" 31#include "timing.h"
32#include "../mm/mmu_decl.h" 32#include "../mm/mmu_decl.h"
33 33
34#define CREATE_TRACE_POINTS
35#include "trace.h"
36
34gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) 37gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
35{ 38{
36 return gfn; 39 return gfn;
37} 40}
38 41
39int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
40{
41 return !!(v->arch.pending_exceptions);
42}
43
44int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
45{
46 /* do real check here */
47 return 1;
48}
49
50int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) 42int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
51{ 43{
52 return !(v->arch.msr & MSR_WE); 44 return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions);
53} 45}
54 46
55 47
@@ -122,13 +114,17 @@ struct kvm *kvm_arch_create_vm(void)
122static void kvmppc_free_vcpus(struct kvm *kvm) 114static void kvmppc_free_vcpus(struct kvm *kvm)
123{ 115{
124 unsigned int i; 116 unsigned int i;
117 struct kvm_vcpu *vcpu;
125 118
126 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 119 kvm_for_each_vcpu(i, vcpu, kvm)
127 if (kvm->vcpus[i]) { 120 kvm_arch_vcpu_free(vcpu);
128 kvm_arch_vcpu_free(kvm->vcpus[i]); 121
129 kvm->vcpus[i] = NULL; 122 mutex_lock(&kvm->lock);
130 } 123 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
131 } 124 kvm->vcpus[i] = NULL;
125
126 atomic_set(&kvm->online_vcpus, 0);
127 mutex_unlock(&kvm->lock);
132} 128}
133 129
134void kvm_arch_sync_events(struct kvm *kvm) 130void kvm_arch_sync_events(struct kvm *kvm)
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
new file mode 100644
index 000000000000..67f219de0455
--- /dev/null
+++ b/arch/powerpc/kvm/trace.h
@@ -0,0 +1,104 @@
1#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
2#define _TRACE_KVM_H
3
4#include <linux/tracepoint.h>
5
6#undef TRACE_SYSTEM
7#define TRACE_SYSTEM kvm
8#define TRACE_INCLUDE_PATH .
9#define TRACE_INCLUDE_FILE trace
10
11/*
12 * Tracepoint for guest mode entry.
13 */
14TRACE_EVENT(kvm_ppc_instr,
15 TP_PROTO(unsigned int inst, unsigned long pc, unsigned int emulate),
16 TP_ARGS(inst, pc, emulate),
17
18 TP_STRUCT__entry(
19 __field( unsigned int, inst )
20 __field( unsigned long, pc )
21 __field( unsigned int, emulate )
22 ),
23
24 TP_fast_assign(
25 __entry->inst = inst;
26 __entry->pc = pc;
27 __entry->emulate = emulate;
28 ),
29
30 TP_printk("inst %u pc 0x%lx emulate %u\n",
31 __entry->inst, __entry->pc, __entry->emulate)
32);
33
34TRACE_EVENT(kvm_stlb_inval,
35 TP_PROTO(unsigned int stlb_index),
36 TP_ARGS(stlb_index),
37
38 TP_STRUCT__entry(
39 __field( unsigned int, stlb_index )
40 ),
41
42 TP_fast_assign(
43 __entry->stlb_index = stlb_index;
44 ),
45
46 TP_printk("stlb_index %u", __entry->stlb_index)
47);
48
49TRACE_EVENT(kvm_stlb_write,
50 TP_PROTO(unsigned int victim, unsigned int tid, unsigned int word0,
51 unsigned int word1, unsigned int word2),
52 TP_ARGS(victim, tid, word0, word1, word2),
53
54 TP_STRUCT__entry(
55 __field( unsigned int, victim )
56 __field( unsigned int, tid )
57 __field( unsigned int, word0 )
58 __field( unsigned int, word1 )
59 __field( unsigned int, word2 )
60 ),
61
62 TP_fast_assign(
63 __entry->victim = victim;
64 __entry->tid = tid;
65 __entry->word0 = word0;
66 __entry->word1 = word1;
67 __entry->word2 = word2;
68 ),
69
70 TP_printk("victim %u tid %u w0 %u w1 %u w2 %u",
71 __entry->victim, __entry->tid, __entry->word0,
72 __entry->word1, __entry->word2)
73);
74
75TRACE_EVENT(kvm_gtlb_write,
76 TP_PROTO(unsigned int gtlb_index, unsigned int tid, unsigned int word0,
77 unsigned int word1, unsigned int word2),
78 TP_ARGS(gtlb_index, tid, word0, word1, word2),
79
80 TP_STRUCT__entry(
81 __field( unsigned int, gtlb_index )
82 __field( unsigned int, tid )
83 __field( unsigned int, word0 )
84 __field( unsigned int, word1 )
85 __field( unsigned int, word2 )
86 ),
87
88 TP_fast_assign(
89 __entry->gtlb_index = gtlb_index;
90 __entry->tid = tid;
91 __entry->word0 = word0;
92 __entry->word1 = word1;
93 __entry->word2 = word2;
94 ),
95
96 TP_printk("gtlb_index %u tid %u w0 %u w1 %u w2 %u",
97 __entry->gtlb_index, __entry->tid, __entry->word0,
98 __entry->word1, __entry->word2)
99);
100
101#endif /* _TRACE_KVM_H */
102
103/* This part must be outside protection */
104#include <trace/define_trace.h>
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 5b7038f248b6..a685652effeb 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -92,15 +92,13 @@ static inline void create_shadowed_slbe(unsigned long ea, int ssize,
92 : "memory" ); 92 : "memory" );
93} 93}
94 94
95void slb_flush_and_rebolt(void) 95static void __slb_flush_and_rebolt(void)
96{ 96{
97 /* If you change this make sure you change SLB_NUM_BOLTED 97 /* If you change this make sure you change SLB_NUM_BOLTED
98 * appropriately too. */ 98 * appropriately too. */
99 unsigned long linear_llp, vmalloc_llp, lflags, vflags; 99 unsigned long linear_llp, vmalloc_llp, lflags, vflags;
100 unsigned long ksp_esid_data, ksp_vsid_data; 100 unsigned long ksp_esid_data, ksp_vsid_data;
101 101
102 WARN_ON(!irqs_disabled());
103
104 linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; 102 linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
105 vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp; 103 vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp;
106 lflags = SLB_VSID_KERNEL | linear_llp; 104 lflags = SLB_VSID_KERNEL | linear_llp;
@@ -117,12 +115,6 @@ void slb_flush_and_rebolt(void)
117 ksp_vsid_data = get_slb_shadow()->save_area[2].vsid; 115 ksp_vsid_data = get_slb_shadow()->save_area[2].vsid;
118 } 116 }
119 117
120 /*
121 * We can't take a PMU exception in the following code, so hard
122 * disable interrupts.
123 */
124 hard_irq_disable();
125
126 /* We need to do this all in asm, so we're sure we don't touch 118 /* We need to do this all in asm, so we're sure we don't touch
127 * the stack between the slbia and rebolting it. */ 119 * the stack between the slbia and rebolting it. */
128 asm volatile("isync\n" 120 asm volatile("isync\n"
@@ -139,6 +131,21 @@ void slb_flush_and_rebolt(void)
139 : "memory"); 131 : "memory");
140} 132}
141 133
134void slb_flush_and_rebolt(void)
135{
136
137 WARN_ON(!irqs_disabled());
138
139 /*
140 * We can't take a PMU exception in the following code, so hard
141 * disable interrupts.
142 */
143 hard_irq_disable();
144
145 __slb_flush_and_rebolt();
146 get_paca()->slb_cache_ptr = 0;
147}
148
142void slb_vmalloc_update(void) 149void slb_vmalloc_update(void)
143{ 150{
144 unsigned long vflags; 151 unsigned long vflags;
@@ -180,12 +187,20 @@ static inline int esids_match(unsigned long addr1, unsigned long addr2)
180/* Flush all user entries from the segment table of the current processor. */ 187/* Flush all user entries from the segment table of the current processor. */
181void switch_slb(struct task_struct *tsk, struct mm_struct *mm) 188void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
182{ 189{
183 unsigned long offset = get_paca()->slb_cache_ptr; 190 unsigned long offset;
184 unsigned long slbie_data = 0; 191 unsigned long slbie_data = 0;
185 unsigned long pc = KSTK_EIP(tsk); 192 unsigned long pc = KSTK_EIP(tsk);
186 unsigned long stack = KSTK_ESP(tsk); 193 unsigned long stack = KSTK_ESP(tsk);
187 unsigned long unmapped_base; 194 unsigned long unmapped_base;
188 195
196 /*
197 * We need interrupts hard-disabled here, not just soft-disabled,
198 * so that a PMU interrupt can't occur, which might try to access
199 * user memory (to get a stack trace) and possible cause an SLB miss
200 * which would update the slb_cache/slb_cache_ptr fields in the PACA.
201 */
202 hard_irq_disable();
203 offset = get_paca()->slb_cache_ptr;
189 if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) && 204 if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
190 offset <= SLB_CACHE_ENTRIES) { 205 offset <= SLB_CACHE_ENTRIES) {
191 int i; 206 int i;
@@ -200,7 +215,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
200 } 215 }
201 asm volatile("isync" : : : "memory"); 216 asm volatile("isync" : : : "memory");
202 } else { 217 } else {
203 slb_flush_and_rebolt(); 218 __slb_flush_and_rebolt();
204 } 219 }
205 220
206 /* Workaround POWER5 < DD2.1 issue */ 221 /* Workaround POWER5 < DD2.1 issue */
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 98cd1dc2ae75..ab5fb48b3e90 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -164,7 +164,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
164{ 164{
165 struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr; 165 struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr;
166 struct stab_entry *ste; 166 struct stab_entry *ste;
167 unsigned long offset = __get_cpu_var(stab_cache_ptr); 167 unsigned long offset;
168 unsigned long pc = KSTK_EIP(tsk); 168 unsigned long pc = KSTK_EIP(tsk);
169 unsigned long stack = KSTK_ESP(tsk); 169 unsigned long stack = KSTK_ESP(tsk);
170 unsigned long unmapped_base; 170 unsigned long unmapped_base;
@@ -172,6 +172,15 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
172 /* Force previous translations to complete. DRENG */ 172 /* Force previous translations to complete. DRENG */
173 asm volatile("isync" : : : "memory"); 173 asm volatile("isync" : : : "memory");
174 174
175 /*
176 * We need interrupts hard-disabled here, not just soft-disabled,
177 * so that a PMU interrupt can't occur, which might try to access
178 * user memory (to get a stack trace) and possible cause an STAB miss
179 * which would update the stab_cache/stab_cache_ptr per-cpu variables.
180 */
181 hard_irq_disable();
182
183 offset = __get_cpu_var(stab_cache_ptr);
175 if (offset <= NR_STAB_CACHE_ENTRIES) { 184 if (offset <= NR_STAB_CACHE_ENTRIES) {
176 int i; 185 int i;
177 186
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 237e3654f48c..464271bea6c9 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -65,6 +65,19 @@ static unsigned int qe_num_of_snum;
65 65
66static phys_addr_t qebase = -1; 66static phys_addr_t qebase = -1;
67 67
68int qe_alive_during_sleep(void)
69{
70 static int ret = -1;
71
72 if (ret != -1)
73 return ret;
74
75 ret = !of_find_compatible_node(NULL, NULL, "fsl,mpc8569-pmc");
76
77 return ret;
78}
79EXPORT_SYMBOL(qe_alive_during_sleep);
80
68phys_addr_t get_qe_base(void) 81phys_addr_t get_qe_base(void)
69{ 82{
70 struct device_node *qe; 83 struct device_node *qe;
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 7238ef4c7a6b..1c866efd217d 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -95,7 +95,6 @@ config S390
95 select HAVE_ARCH_TRACEHOOK 95 select HAVE_ARCH_TRACEHOOK
96 select INIT_ALL_POSSIBLE 96 select INIT_ALL_POSSIBLE
97 select HAVE_PERF_COUNTERS 97 select HAVE_PERF_COUNTERS
98 select GENERIC_ATOMIC64 if !64BIT
99 98
100config SCHED_OMIT_FRAME_POINTER 99config SCHED_OMIT_FRAME_POINTER
101 bool 100 bool
@@ -481,13 +480,6 @@ config CMM_IUCV
481 Select this option to enable the special message interface to 480 Select this option to enable the special message interface to
482 the cooperative memory management. 481 the cooperative memory management.
483 482
484config PAGE_STATES
485 bool "Unused page notification"
486 help
487 This enables the notification of unused pages to the
488 hypervisor. The ESSA instruction is used to do the states
489 changes between a page that has content and the unused state.
490
491config APPLDATA_BASE 483config APPLDATA_BASE
492 bool "Linux - VM Monitor Stream, base infrastructure" 484 bool "Linux - VM Monitor Stream, base infrastructure"
493 depends on PROC_FS 485 depends on PROC_FS
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 0ff387cebf88..fc8fb20e7fc0 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -88,8 +88,7 @@ LDFLAGS_vmlinux := -e start
88head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o 88head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o
89 89
90core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ 90core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
91 arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ \ 91 arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/
92 arch/s390/power/
93 92
94libs-y += arch/s390/lib/ 93libs-y += arch/s390/lib/
95drivers-y += drivers/s390/ 94drivers-y += drivers/s390/
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index 4aba83b31596..2bc479ab3a66 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -250,8 +250,9 @@ static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key,
250 const u8 *temp_key = key; 250 const u8 *temp_key = key;
251 u32 *flags = &tfm->crt_flags; 251 u32 *flags = &tfm->crt_flags;
252 252
253 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { 253 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE)) &&
254 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; 254 (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
255 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
255 return -EINVAL; 256 return -EINVAL;
256 } 257 }
257 for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { 258 for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
@@ -411,9 +412,9 @@ static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
411 412
412 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 413 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
413 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], 414 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
414 DES_KEY_SIZE))) { 415 DES_KEY_SIZE)) &&
415 416 (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
416 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; 417 *flags |= CRYPTO_TFM_RES_WEAK_KEY;
417 return -EINVAL; 418 return -EINVAL;
418 } 419 }
419 for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { 420 for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c
index e85ba348722a..f6de7826c979 100644
--- a/arch/s390/crypto/sha1_s390.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -46,12 +46,38 @@ static int sha1_init(struct shash_desc *desc)
46 return 0; 46 return 0;
47} 47}
48 48
49static int sha1_export(struct shash_desc *desc, void *out)
50{
51 struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
52 struct sha1_state *octx = out;
53
54 octx->count = sctx->count;
55 memcpy(octx->state, sctx->state, sizeof(octx->state));
56 memcpy(octx->buffer, sctx->buf, sizeof(octx->buffer));
57 return 0;
58}
59
60static int sha1_import(struct shash_desc *desc, const void *in)
61{
62 struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
63 const struct sha1_state *ictx = in;
64
65 sctx->count = ictx->count;
66 memcpy(sctx->state, ictx->state, sizeof(ictx->state));
67 memcpy(sctx->buf, ictx->buffer, sizeof(ictx->buffer));
68 sctx->func = KIMD_SHA_1;
69 return 0;
70}
71
49static struct shash_alg alg = { 72static struct shash_alg alg = {
50 .digestsize = SHA1_DIGEST_SIZE, 73 .digestsize = SHA1_DIGEST_SIZE,
51 .init = sha1_init, 74 .init = sha1_init,
52 .update = s390_sha_update, 75 .update = s390_sha_update,
53 .final = s390_sha_final, 76 .final = s390_sha_final,
77 .export = sha1_export,
78 .import = sha1_import,
54 .descsize = sizeof(struct s390_sha_ctx), 79 .descsize = sizeof(struct s390_sha_ctx),
80 .statesize = sizeof(struct sha1_state),
55 .base = { 81 .base = {
56 .cra_name = "sha1", 82 .cra_name = "sha1",
57 .cra_driver_name= "sha1-s390", 83 .cra_driver_name= "sha1-s390",
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index f9fefc569632..61a7db372121 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -42,12 +42,38 @@ static int sha256_init(struct shash_desc *desc)
42 return 0; 42 return 0;
43} 43}
44 44
45static int sha256_export(struct shash_desc *desc, void *out)
46{
47 struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
48 struct sha256_state *octx = out;
49
50 octx->count = sctx->count;
51 memcpy(octx->state, sctx->state, sizeof(octx->state));
52 memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
53 return 0;
54}
55
56static int sha256_import(struct shash_desc *desc, const void *in)
57{
58 struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
59 const struct sha256_state *ictx = in;
60
61 sctx->count = ictx->count;
62 memcpy(sctx->state, ictx->state, sizeof(ictx->state));
63 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
64 sctx->func = KIMD_SHA_256;
65 return 0;
66}
67
45static struct shash_alg alg = { 68static struct shash_alg alg = {
46 .digestsize = SHA256_DIGEST_SIZE, 69 .digestsize = SHA256_DIGEST_SIZE,
47 .init = sha256_init, 70 .init = sha256_init,
48 .update = s390_sha_update, 71 .update = s390_sha_update,
49 .final = s390_sha_final, 72 .final = s390_sha_final,
73 .export = sha256_export,
74 .import = sha256_import,
50 .descsize = sizeof(struct s390_sha_ctx), 75 .descsize = sizeof(struct s390_sha_ctx),
76 .statesize = sizeof(struct sha256_state),
51 .base = { 77 .base = {
52 .cra_name = "sha256", 78 .cra_name = "sha256",
53 .cra_driver_name= "sha256-s390", 79 .cra_driver_name= "sha256-s390",
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c
index 83192bfc8048..4bf73d0dc525 100644
--- a/arch/s390/crypto/sha512_s390.c
+++ b/arch/s390/crypto/sha512_s390.c
@@ -13,7 +13,10 @@
13 * 13 *
14 */ 14 */
15#include <crypto/internal/hash.h> 15#include <crypto/internal/hash.h>
16#include <crypto/sha.h>
17#include <linux/errno.h>
16#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/kernel.h>
17#include <linux/module.h> 20#include <linux/module.h>
18 21
19#include "sha.h" 22#include "sha.h"
@@ -37,12 +40,42 @@ static int sha512_init(struct shash_desc *desc)
37 return 0; 40 return 0;
38} 41}
39 42
43static int sha512_export(struct shash_desc *desc, void *out)
44{
45 struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
46 struct sha512_state *octx = out;
47
48 octx->count[0] = sctx->count;
49 octx->count[1] = 0;
50 memcpy(octx->state, sctx->state, sizeof(octx->state));
51 memcpy(octx->buf, sctx->buf, sizeof(octx->buf));
52 return 0;
53}
54
55static int sha512_import(struct shash_desc *desc, const void *in)
56{
57 struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
58 const struct sha512_state *ictx = in;
59
60 if (unlikely(ictx->count[1]))
61 return -ERANGE;
62 sctx->count = ictx->count[0];
63
64 memcpy(sctx->state, ictx->state, sizeof(ictx->state));
65 memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf));
66 sctx->func = KIMD_SHA_512;
67 return 0;
68}
69
40static struct shash_alg sha512_alg = { 70static struct shash_alg sha512_alg = {
41 .digestsize = SHA512_DIGEST_SIZE, 71 .digestsize = SHA512_DIGEST_SIZE,
42 .init = sha512_init, 72 .init = sha512_init,
43 .update = s390_sha_update, 73 .update = s390_sha_update,
44 .final = s390_sha_final, 74 .final = s390_sha_final,
75 .export = sha512_export,
76 .import = sha512_import,
45 .descsize = sizeof(struct s390_sha_ctx), 77 .descsize = sizeof(struct s390_sha_ctx),
78 .statesize = sizeof(struct sha512_state),
46 .base = { 79 .base = {
47 .cra_name = "sha512", 80 .cra_name = "sha512",
48 .cra_driver_name= "sha512-s390", 81 .cra_driver_name= "sha512-s390",
@@ -78,7 +111,10 @@ static struct shash_alg sha384_alg = {
78 .init = sha384_init, 111 .init = sha384_init,
79 .update = s390_sha_update, 112 .update = s390_sha_update,
80 .final = s390_sha_final, 113 .final = s390_sha_final,
114 .export = sha512_export,
115 .import = sha512_import,
81 .descsize = sizeof(struct s390_sha_ctx), 116 .descsize = sizeof(struct s390_sha_ctx),
117 .statesize = sizeof(struct sha512_state),
82 .base = { 118 .base = {
83 .cra_name = "sha384", 119 .cra_name = "sha384",
84 .cra_driver_name= "sha384-s390", 120 .cra_driver_name= "sha384-s390",
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 5a805df216bb..bd9914b89488 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -355,11 +355,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb,
355{ 355{
356 struct dentry *dentry; 356 struct dentry *dentry;
357 struct inode *inode; 357 struct inode *inode;
358 struct qstr qname;
359 358
360 qname.name = name;
361 qname.len = strlen(name);
362 qname.hash = full_name_hash(name, qname.len);
363 mutex_lock(&parent->d_inode->i_mutex); 359 mutex_lock(&parent->d_inode->i_mutex);
364 dentry = lookup_one_len(name, parent, strlen(name)); 360 dentry = lookup_one_len(name, parent, strlen(name));
365 if (IS_ERR(dentry)) { 361 if (IS_ERR(dentry)) {
@@ -426,7 +422,7 @@ struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir,
426 char tmp[TMP_SIZE]; 422 char tmp[TMP_SIZE];
427 struct dentry *dentry; 423 struct dentry *dentry;
428 424
429 snprintf(tmp, TMP_SIZE, "%lld\n", (unsigned long long int)value); 425 snprintf(tmp, TMP_SIZE, "%llu\n", (unsigned long long int)value);
430 buffer = kstrdup(tmp, GFP_KERNEL); 426 buffer = kstrdup(tmp, GFP_KERNEL);
431 if (!buffer) 427 if (!buffer)
432 return ERR_PTR(-ENOMEM); 428 return ERR_PTR(-ENOMEM);
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
index c7d0abfb0f00..ae7c8f9f94a5 100644
--- a/arch/s390/include/asm/atomic.h
+++ b/arch/s390/include/asm/atomic.h
@@ -1,33 +1,23 @@
1#ifndef __ARCH_S390_ATOMIC__ 1#ifndef __ARCH_S390_ATOMIC__
2#define __ARCH_S390_ATOMIC__ 2#define __ARCH_S390_ATOMIC__
3 3
4#include <linux/compiler.h>
5#include <linux/types.h>
6
7/* 4/*
8 * include/asm-s390/atomic.h 5 * Copyright 1999,2009 IBM Corp.
6 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
7 * Denis Joseph Barrow,
8 * Arnd Bergmann <arndb@de.ibm.com>,
9 * 9 *
10 * S390 version 10 * Atomic operations that C can't guarantee us.
11 * Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation 11 * Useful for resource counting etc.
12 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 12 * s390 uses 'Compare And Swap' for atomicity in SMP enviroment.
13 * Denis Joseph Barrow,
14 * Arnd Bergmann (arndb@de.ibm.com)
15 *
16 * Derived from "include/asm-i386/bitops.h"
17 * Copyright (C) 1992, Linus Torvalds
18 * 13 *
19 */ 14 */
20 15
21/* 16#include <linux/compiler.h>
22 * Atomic operations that C can't guarantee us. Useful for 17#include <linux/types.h>
23 * resource counting etc..
24 * S390 uses 'Compare And Swap' for atomicity in SMP enviroment
25 */
26 18
27#define ATOMIC_INIT(i) { (i) } 19#define ATOMIC_INIT(i) { (i) }
28 20
29#ifdef __KERNEL__
30
31#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) 21#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
32 22
33#define __CS_LOOP(ptr, op_val, op_string) ({ \ 23#define __CS_LOOP(ptr, op_val, op_string) ({ \
@@ -77,7 +67,7 @@ static inline void atomic_set(atomic_t *v, int i)
77 barrier(); 67 barrier();
78} 68}
79 69
80static __inline__ int atomic_add_return(int i, atomic_t * v) 70static inline int atomic_add_return(int i, atomic_t *v)
81{ 71{
82 return __CS_LOOP(v, i, "ar"); 72 return __CS_LOOP(v, i, "ar");
83} 73}
@@ -87,7 +77,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
87#define atomic_inc_return(_v) atomic_add_return(1, _v) 77#define atomic_inc_return(_v) atomic_add_return(1, _v)
88#define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) 78#define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0)
89 79
90static __inline__ int atomic_sub_return(int i, atomic_t * v) 80static inline int atomic_sub_return(int i, atomic_t *v)
91{ 81{
92 return __CS_LOOP(v, i, "sr"); 82 return __CS_LOOP(v, i, "sr");
93} 83}
@@ -97,19 +87,19 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
97#define atomic_dec_return(_v) atomic_sub_return(1, _v) 87#define atomic_dec_return(_v) atomic_sub_return(1, _v)
98#define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) 88#define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0)
99 89
100static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) 90static inline void atomic_clear_mask(unsigned long mask, atomic_t *v)
101{ 91{
102 __CS_LOOP(v, ~mask, "nr"); 92 __CS_LOOP(v, ~mask, "nr");
103} 93}
104 94
105static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) 95static inline void atomic_set_mask(unsigned long mask, atomic_t *v)
106{ 96{
107 __CS_LOOP(v, mask, "or"); 97 __CS_LOOP(v, mask, "or");
108} 98}
109 99
110#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 100#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
111 101
112static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) 102static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
113{ 103{
114#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) 104#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
115 asm volatile( 105 asm volatile(
@@ -127,7 +117,7 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
127 return old; 117 return old;
128} 118}
129 119
130static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) 120static inline int atomic_add_unless(atomic_t *v, int a, int u)
131{ 121{
132 int c, old; 122 int c, old;
133 c = atomic_read(v); 123 c = atomic_read(v);
@@ -146,9 +136,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
146 136
147#undef __CS_LOOP 137#undef __CS_LOOP
148 138
149#ifdef __s390x__
150#define ATOMIC64_INIT(i) { (i) } 139#define ATOMIC64_INIT(i) { (i) }
151 140
141#ifdef CONFIG_64BIT
142
152#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) 143#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
153 144
154#define __CSG_LOOP(ptr, op_val, op_string) ({ \ 145#define __CSG_LOOP(ptr, op_val, op_string) ({ \
@@ -162,7 +153,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
162 : "=&d" (old_val), "=&d" (new_val), \ 153 : "=&d" (old_val), "=&d" (new_val), \
163 "=Q" (((atomic_t *)(ptr))->counter) \ 154 "=Q" (((atomic_t *)(ptr))->counter) \
164 : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ 155 : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \
165 : "cc", "memory" ); \ 156 : "cc", "memory"); \
166 new_val; \ 157 new_val; \
167}) 158})
168 159
@@ -180,7 +171,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
180 "=m" (((atomic_t *)(ptr))->counter) \ 171 "=m" (((atomic_t *)(ptr))->counter) \
181 : "a" (ptr), "d" (op_val), \ 172 : "a" (ptr), "d" (op_val), \
182 "m" (((atomic_t *)(ptr))->counter) \ 173 "m" (((atomic_t *)(ptr))->counter) \
183 : "cc", "memory" ); \ 174 : "cc", "memory"); \
184 new_val; \ 175 new_val; \
185}) 176})
186 177
@@ -198,39 +189,29 @@ static inline void atomic64_set(atomic64_t *v, long long i)
198 barrier(); 189 barrier();
199} 190}
200 191
201static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) 192static inline long long atomic64_add_return(long long i, atomic64_t *v)
202{ 193{
203 return __CSG_LOOP(v, i, "agr"); 194 return __CSG_LOOP(v, i, "agr");
204} 195}
205#define atomic64_add(_i, _v) atomic64_add_return(_i, _v)
206#define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0)
207#define atomic64_inc(_v) atomic64_add_return(1, _v)
208#define atomic64_inc_return(_v) atomic64_add_return(1, _v)
209#define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0)
210 196
211static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) 197static inline long long atomic64_sub_return(long long i, atomic64_t *v)
212{ 198{
213 return __CSG_LOOP(v, i, "sgr"); 199 return __CSG_LOOP(v, i, "sgr");
214} 200}
215#define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v)
216#define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0)
217#define atomic64_dec(_v) atomic64_sub_return(1, _v)
218#define atomic64_dec_return(_v) atomic64_sub_return(1, _v)
219#define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0)
220 201
221static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) 202static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v)
222{ 203{
223 __CSG_LOOP(v, ~mask, "ngr"); 204 __CSG_LOOP(v, ~mask, "ngr");
224} 205}
225 206
226static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) 207static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v)
227{ 208{
228 __CSG_LOOP(v, mask, "ogr"); 209 __CSG_LOOP(v, mask, "ogr");
229} 210}
230 211
231#define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) 212#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
232 213
233static __inline__ long long atomic64_cmpxchg(atomic64_t *v, 214static inline long long atomic64_cmpxchg(atomic64_t *v,
234 long long old, long long new) 215 long long old, long long new)
235{ 216{
236#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) 217#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
@@ -249,8 +230,112 @@ static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
249 return old; 230 return old;
250} 231}
251 232
252static __inline__ int atomic64_add_unless(atomic64_t *v, 233#undef __CSG_LOOP
253 long long a, long long u) 234
235#else /* CONFIG_64BIT */
236
237typedef struct {
238 long long counter;
239} atomic64_t;
240
241static inline long long atomic64_read(const atomic64_t *v)
242{
243 register_pair rp;
244
245 asm volatile(
246 " lm %0,%N0,0(%1)"
247 : "=&d" (rp)
248 : "a" (&v->counter), "m" (v->counter)
249 );
250 return rp.pair;
251}
252
253static inline void atomic64_set(atomic64_t *v, long long i)
254{
255 register_pair rp = {.pair = i};
256
257 asm volatile(
258 " stm %1,%N1,0(%2)"
259 : "=m" (v->counter)
260 : "d" (rp), "a" (&v->counter)
261 );
262}
263
264static inline long long atomic64_xchg(atomic64_t *v, long long new)
265{
266 register_pair rp_new = {.pair = new};
267 register_pair rp_old;
268
269 asm volatile(
270 " lm %0,%N0,0(%2)\n"
271 "0: cds %0,%3,0(%2)\n"
272 " jl 0b\n"
273 : "=&d" (rp_old), "+m" (v->counter)
274 : "a" (&v->counter), "d" (rp_new)
275 : "cc");
276 return rp_old.pair;
277}
278
279static inline long long atomic64_cmpxchg(atomic64_t *v,
280 long long old, long long new)
281{
282 register_pair rp_old = {.pair = old};
283 register_pair rp_new = {.pair = new};
284
285 asm volatile(
286 " cds %0,%3,0(%2)"
287 : "+&d" (rp_old), "+m" (v->counter)
288 : "a" (&v->counter), "d" (rp_new)
289 : "cc");
290 return rp_old.pair;
291}
292
293
294static inline long long atomic64_add_return(long long i, atomic64_t *v)
295{
296 long long old, new;
297
298 do {
299 old = atomic64_read(v);
300 new = old + i;
301 } while (atomic64_cmpxchg(v, old, new) != old);
302 return new;
303}
304
305static inline long long atomic64_sub_return(long long i, atomic64_t *v)
306{
307 long long old, new;
308
309 do {
310 old = atomic64_read(v);
311 new = old - i;
312 } while (atomic64_cmpxchg(v, old, new) != old);
313 return new;
314}
315
316static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v)
317{
318 long long old, new;
319
320 do {
321 old = atomic64_read(v);
322 new = old | mask;
323 } while (atomic64_cmpxchg(v, old, new) != old);
324}
325
326static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v)
327{
328 long long old, new;
329
330 do {
331 old = atomic64_read(v);
332 new = old & mask;
333 } while (atomic64_cmpxchg(v, old, new) != old);
334}
335
336#endif /* CONFIG_64BIT */
337
338static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
254{ 339{
255 long long c, old; 340 long long c, old;
256 c = atomic64_read(v); 341 c = atomic64_read(v);
@@ -265,15 +350,17 @@ static __inline__ int atomic64_add_unless(atomic64_t *v,
265 return c != u; 350 return c != u;
266} 351}
267 352
268#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) 353#define atomic64_add(_i, _v) atomic64_add_return(_i, _v)
269 354#define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0)
270#undef __CSG_LOOP 355#define atomic64_inc(_v) atomic64_add_return(1, _v)
271 356#define atomic64_inc_return(_v) atomic64_add_return(1, _v)
272#else /* __s390x__ */ 357#define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0)
273 358#define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v)
274#include <asm-generic/atomic64.h> 359#define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0)
275 360#define atomic64_dec(_v) atomic64_sub_return(1, _v)
276#endif /* __s390x__ */ 361#define atomic64_dec_return(_v) atomic64_sub_return(1, _v)
362#define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0)
363#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
277 364
278#define smp_mb__before_atomic_dec() smp_mb() 365#define smp_mb__before_atomic_dec() smp_mb()
279#define smp_mb__after_atomic_dec() smp_mb() 366#define smp_mb__after_atomic_dec() smp_mb()
@@ -281,5 +368,5 @@ static __inline__ int atomic64_add_unless(atomic64_t *v,
281#define smp_mb__after_atomic_inc() smp_mb() 368#define smp_mb__after_atomic_inc() smp_mb()
282 369
283#include <asm-generic/atomic-long.h> 370#include <asm-generic/atomic-long.h>
284#endif /* __KERNEL__ */ 371
285#endif /* __ARCH_S390_ATOMIC__ */ 372#endif /* __ARCH_S390_ATOMIC__ */
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index d5a8e7c1477c..6c00f6800a34 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -78,28 +78,11 @@ csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum)
78 */ 78 */
79static inline __sum16 csum_fold(__wsum sum) 79static inline __sum16 csum_fold(__wsum sum)
80{ 80{
81#ifndef __s390x__ 81 u32 csum = (__force u32) sum;
82 register_pair rp;
83 82
84 asm volatile( 83 csum += (csum >> 16) + (csum << 16);
85 " slr %N1,%N1\n" /* %0 = H L */ 84 csum >>= 16;
86 " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ 85 return (__force __sum16) ~csum;
87 " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */
88 " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */
89 " alr %0,%1\n" /* %0 = H+L+C L+H */
90 " srl %0,16\n" /* %0 = H+L+C */
91 : "+&d" (sum), "=d" (rp) : : "cc");
92#else /* __s390x__ */
93 asm volatile(
94 " sr 3,3\n" /* %0 = H*65536 + L */
95 " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */
96 " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */
97 " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */
98 " alr %0,2\n" /* %0 = H+L+C L+H */
99 " srl %0,16\n" /* %0 = H+L+C */
100 : "+&d" (sum) : : "cc", "2", "3");
101#endif /* __s390x__ */
102 return (__force __sum16) ~sum;
103} 86}
104 87
105/* 88/*
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h
index 807997f7414b..4943654ed7fd 100644
--- a/arch/s390/include/asm/chsc.h
+++ b/arch/s390/include/asm/chsc.h
@@ -125,4 +125,32 @@ struct chsc_cpd_info {
125#define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) 125#define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info)
126#define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) 126#define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal)
127 127
128#ifdef __KERNEL__
129
130struct css_general_char {
131 u64 : 12;
132 u32 dynio : 1; /* bit 12 */
133 u32 : 28;
134 u32 aif : 1; /* bit 41 */
135 u32 : 3;
136 u32 mcss : 1; /* bit 45 */
137 u32 fcs : 1; /* bit 46 */
138 u32 : 1;
139 u32 ext_mb : 1; /* bit 48 */
140 u32 : 7;
141 u32 aif_tdd : 1; /* bit 56 */
142 u32 : 1;
143 u32 qebsm : 1; /* bit 58 */
144 u32 : 8;
145 u32 aif_osa : 1; /* bit 67 */
146 u32 : 14;
147 u32 cib : 1; /* bit 82 */
148 u32 : 5;
149 u32 fcx : 1; /* bit 88 */
150 u32 : 7;
151}__attribute__((packed));
152
153extern struct css_general_char css_general_characteristics;
154
155#endif /* __KERNEL__ */
128#endif 156#endif
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 619bf94b11f1..e85679af54dd 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -15,228 +15,7 @@
15#define LPM_ANYPATH 0xff 15#define LPM_ANYPATH 0xff
16#define __MAX_CSSID 0 16#define __MAX_CSSID 0
17 17
18/** 18#include <asm/scsw.h>
19 * struct cmd_scsw - command-mode subchannel status word
20 * @key: subchannel key
21 * @sctl: suspend control
22 * @eswf: esw format
23 * @cc: deferred condition code
24 * @fmt: format
25 * @pfch: prefetch
26 * @isic: initial-status interruption control
27 * @alcc: address-limit checking control
28 * @ssi: suppress-suspended interruption
29 * @zcc: zero condition code
30 * @ectl: extended control
31 * @pno: path not operational
32 * @res: reserved
33 * @fctl: function control
34 * @actl: activity control
35 * @stctl: status control
36 * @cpa: channel program address
37 * @dstat: device status
38 * @cstat: subchannel status
39 * @count: residual count
40 */
41struct cmd_scsw {
42 __u32 key : 4;
43 __u32 sctl : 1;
44 __u32 eswf : 1;
45 __u32 cc : 2;
46 __u32 fmt : 1;
47 __u32 pfch : 1;
48 __u32 isic : 1;
49 __u32 alcc : 1;
50 __u32 ssi : 1;
51 __u32 zcc : 1;
52 __u32 ectl : 1;
53 __u32 pno : 1;
54 __u32 res : 1;
55 __u32 fctl : 3;
56 __u32 actl : 7;
57 __u32 stctl : 5;
58 __u32 cpa;
59 __u32 dstat : 8;
60 __u32 cstat : 8;
61 __u32 count : 16;
62} __attribute__ ((packed));
63
64/**
65 * struct tm_scsw - transport-mode subchannel status word
66 * @key: subchannel key
67 * @eswf: esw format
68 * @cc: deferred condition code
69 * @fmt: format
70 * @x: IRB-format control
71 * @q: interrogate-complete
72 * @ectl: extended control
73 * @pno: path not operational
74 * @fctl: function control
75 * @actl: activity control
76 * @stctl: status control
77 * @tcw: TCW address
78 * @dstat: device status
79 * @cstat: subchannel status
80 * @fcxs: FCX status
81 * @schxs: subchannel-extended status
82 */
83struct tm_scsw {
84 u32 key:4;
85 u32 :1;
86 u32 eswf:1;
87 u32 cc:2;
88 u32 fmt:3;
89 u32 x:1;
90 u32 q:1;
91 u32 :1;
92 u32 ectl:1;
93 u32 pno:1;
94 u32 :1;
95 u32 fctl:3;
96 u32 actl:7;
97 u32 stctl:5;
98 u32 tcw;
99 u32 dstat:8;
100 u32 cstat:8;
101 u32 fcxs:8;
102 u32 schxs:8;
103} __attribute__ ((packed));
104
105/**
106 * union scsw - subchannel status word
107 * @cmd: command-mode SCSW
108 * @tm: transport-mode SCSW
109 */
110union scsw {
111 struct cmd_scsw cmd;
112 struct tm_scsw tm;
113} __attribute__ ((packed));
114
115int scsw_is_tm(union scsw *scsw);
116u32 scsw_key(union scsw *scsw);
117u32 scsw_eswf(union scsw *scsw);
118u32 scsw_cc(union scsw *scsw);
119u32 scsw_ectl(union scsw *scsw);
120u32 scsw_pno(union scsw *scsw);
121u32 scsw_fctl(union scsw *scsw);
122u32 scsw_actl(union scsw *scsw);
123u32 scsw_stctl(union scsw *scsw);
124u32 scsw_dstat(union scsw *scsw);
125u32 scsw_cstat(union scsw *scsw);
126int scsw_is_solicited(union scsw *scsw);
127int scsw_is_valid_key(union scsw *scsw);
128int scsw_is_valid_eswf(union scsw *scsw);
129int scsw_is_valid_cc(union scsw *scsw);
130int scsw_is_valid_ectl(union scsw *scsw);
131int scsw_is_valid_pno(union scsw *scsw);
132int scsw_is_valid_fctl(union scsw *scsw);
133int scsw_is_valid_actl(union scsw *scsw);
134int scsw_is_valid_stctl(union scsw *scsw);
135int scsw_is_valid_dstat(union scsw *scsw);
136int scsw_is_valid_cstat(union scsw *scsw);
137int scsw_cmd_is_valid_key(union scsw *scsw);
138int scsw_cmd_is_valid_sctl(union scsw *scsw);
139int scsw_cmd_is_valid_eswf(union scsw *scsw);
140int scsw_cmd_is_valid_cc(union scsw *scsw);
141int scsw_cmd_is_valid_fmt(union scsw *scsw);
142int scsw_cmd_is_valid_pfch(union scsw *scsw);
143int scsw_cmd_is_valid_isic(union scsw *scsw);
144int scsw_cmd_is_valid_alcc(union scsw *scsw);
145int scsw_cmd_is_valid_ssi(union scsw *scsw);
146int scsw_cmd_is_valid_zcc(union scsw *scsw);
147int scsw_cmd_is_valid_ectl(union scsw *scsw);
148int scsw_cmd_is_valid_pno(union scsw *scsw);
149int scsw_cmd_is_valid_fctl(union scsw *scsw);
150int scsw_cmd_is_valid_actl(union scsw *scsw);
151int scsw_cmd_is_valid_stctl(union scsw *scsw);
152int scsw_cmd_is_valid_dstat(union scsw *scsw);
153int scsw_cmd_is_valid_cstat(union scsw *scsw);
154int scsw_cmd_is_solicited(union scsw *scsw);
155int scsw_tm_is_valid_key(union scsw *scsw);
156int scsw_tm_is_valid_eswf(union scsw *scsw);
157int scsw_tm_is_valid_cc(union scsw *scsw);
158int scsw_tm_is_valid_fmt(union scsw *scsw);
159int scsw_tm_is_valid_x(union scsw *scsw);
160int scsw_tm_is_valid_q(union scsw *scsw);
161int scsw_tm_is_valid_ectl(union scsw *scsw);
162int scsw_tm_is_valid_pno(union scsw *scsw);
163int scsw_tm_is_valid_fctl(union scsw *scsw);
164int scsw_tm_is_valid_actl(union scsw *scsw);
165int scsw_tm_is_valid_stctl(union scsw *scsw);
166int scsw_tm_is_valid_dstat(union scsw *scsw);
167int scsw_tm_is_valid_cstat(union scsw *scsw);
168int scsw_tm_is_valid_fcxs(union scsw *scsw);
169int scsw_tm_is_valid_schxs(union scsw *scsw);
170int scsw_tm_is_solicited(union scsw *scsw);
171
172#define SCSW_FCTL_CLEAR_FUNC 0x1
173#define SCSW_FCTL_HALT_FUNC 0x2
174#define SCSW_FCTL_START_FUNC 0x4
175
176#define SCSW_ACTL_SUSPENDED 0x1
177#define SCSW_ACTL_DEVACT 0x2
178#define SCSW_ACTL_SCHACT 0x4
179#define SCSW_ACTL_CLEAR_PEND 0x8
180#define SCSW_ACTL_HALT_PEND 0x10
181#define SCSW_ACTL_START_PEND 0x20
182#define SCSW_ACTL_RESUME_PEND 0x40
183
184#define SCSW_STCTL_STATUS_PEND 0x1
185#define SCSW_STCTL_SEC_STATUS 0x2
186#define SCSW_STCTL_PRIM_STATUS 0x4
187#define SCSW_STCTL_INTER_STATUS 0x8
188#define SCSW_STCTL_ALERT_STATUS 0x10
189
190#define DEV_STAT_ATTENTION 0x80
191#define DEV_STAT_STAT_MOD 0x40
192#define DEV_STAT_CU_END 0x20
193#define DEV_STAT_BUSY 0x10
194#define DEV_STAT_CHN_END 0x08
195#define DEV_STAT_DEV_END 0x04
196#define DEV_STAT_UNIT_CHECK 0x02
197#define DEV_STAT_UNIT_EXCEP 0x01
198
199#define SCHN_STAT_PCI 0x80
200#define SCHN_STAT_INCORR_LEN 0x40
201#define SCHN_STAT_PROG_CHECK 0x20
202#define SCHN_STAT_PROT_CHECK 0x10
203#define SCHN_STAT_CHN_DATA_CHK 0x08
204#define SCHN_STAT_CHN_CTRL_CHK 0x04
205#define SCHN_STAT_INTF_CTRL_CHK 0x02
206#define SCHN_STAT_CHAIN_CHECK 0x01
207
208/*
209 * architectured values for first sense byte
210 */
211#define SNS0_CMD_REJECT 0x80
212#define SNS_CMD_REJECT SNS0_CMD_REJEC
213#define SNS0_INTERVENTION_REQ 0x40
214#define SNS0_BUS_OUT_CHECK 0x20
215#define SNS0_EQUIPMENT_CHECK 0x10
216#define SNS0_DATA_CHECK 0x08
217#define SNS0_OVERRUN 0x04
218#define SNS0_INCOMPL_DOMAIN 0x01
219
220/*
221 * architectured values for second sense byte
222 */
223#define SNS1_PERM_ERR 0x80
224#define SNS1_INV_TRACK_FORMAT 0x40
225#define SNS1_EOC 0x20
226#define SNS1_MESSAGE_TO_OPER 0x10
227#define SNS1_NO_REC_FOUND 0x08
228#define SNS1_FILE_PROTECTED 0x04
229#define SNS1_WRITE_INHIBITED 0x02
230#define SNS1_INPRECISE_END 0x01
231
232/*
233 * architectured values for third sense byte
234 */
235#define SNS2_REQ_INH_WRITE 0x80
236#define SNS2_CORRECTABLE 0x40
237#define SNS2_FIRST_LOG_ERR 0x20
238#define SNS2_ENV_DATA_PRESENT 0x10
239#define SNS2_INPRECISE_END 0x04
240 19
241/** 20/**
242 * struct ccw1 - channel command word 21 * struct ccw1 - channel command word
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h
new file mode 100644
index 000000000000..471234b90574
--- /dev/null
+++ b/arch/s390/include/asm/cpu.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright IBM Corp. 2000,2009
3 * Author(s): Hartmut Penner <hp@de.ibm.com>,
4 * Martin Schwidefsky <schwidefsky@de.ibm.com>,
5 * Christian Ehrhardt <ehrhardt@de.ibm.com>,
6 */
7
8#ifndef _ASM_S390_CPU_H
9#define _ASM_S390_CPU_H
10
11#define MAX_CPU_ADDRESS 255
12
13#ifndef __ASSEMBLY__
14
15#include <linux/types.h>
16
17struct cpuid
18{
19 unsigned int version : 8;
20 unsigned int ident : 24;
21 unsigned int machine : 16;
22 unsigned int unused : 16;
23} __packed;
24
25#endif /* __ASSEMBLY__ */
26#endif /* _ASM_S390_CPU_H */
diff --git a/arch/s390/include/asm/cpuid.h b/arch/s390/include/asm/cpuid.h
deleted file mode 100644
index 07836a2e5222..000000000000
--- a/arch/s390/include/asm/cpuid.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Copyright IBM Corp. 2000,2009
3 * Author(s): Hartmut Penner <hp@de.ibm.com>,
4 * Martin Schwidefsky <schwidefsky@de.ibm.com>
5 * Christian Ehrhardt <ehrhardt@de.ibm.com>
6 */
7
8#ifndef _ASM_S390_CPUID_H_
9#define _ASM_S390_CPUID_H_
10
11/*
12 * CPU type and hardware bug flags. Kept separately for each CPU.
13 * Members of this structure are referenced in head.S, so think twice
14 * before touching them. [mj]
15 */
16
17typedef struct
18{
19 unsigned int version : 8;
20 unsigned int ident : 24;
21 unsigned int machine : 16;
22 unsigned int unused : 16;
23} __attribute__ ((packed)) cpuid_t;
24
25#endif /* _ASM_S390_CPUID_H_ */
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
index 31ed5686a968..18124b75a7ab 100644
--- a/arch/s390/include/asm/debug.h
+++ b/arch/s390/include/asm/debug.h
@@ -167,6 +167,10 @@ debug_text_event(debug_info_t* id, int level, const char* txt)
167 return debug_event_common(id,level,txt,strlen(txt)); 167 return debug_event_common(id,level,txt,strlen(txt));
168} 168}
169 169
170/*
171 * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
172 * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details!
173 */
170extern debug_entry_t * 174extern debug_entry_t *
171debug_sprintf_event(debug_info_t* id,int level,char *string,...) 175debug_sprintf_event(debug_info_t* id,int level,char *string,...)
172 __attribute__ ((format(printf, 3, 4))); 176 __attribute__ ((format(printf, 3, 4)));
@@ -206,7 +210,10 @@ debug_text_exception(debug_info_t* id, int level, const char* txt)
206 return debug_exception_common(id,level,txt,strlen(txt)); 210 return debug_exception_common(id,level,txt,strlen(txt));
207} 211}
208 212
209 213/*
214 * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
215 * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details!
216 */
210extern debug_entry_t * 217extern debug_entry_t *
211debug_sprintf_exception(debug_info_t* id,int level,char *string,...) 218debug_sprintf_exception(debug_info_t* id,int level,char *string,...)
212 __attribute__ ((format(printf, 3, 4))); 219 __attribute__ ((format(printf, 3, 4)));
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h
index 89ec7056da28..498bc3892385 100644
--- a/arch/s390/include/asm/hardirq.h
+++ b/arch/s390/include/asm/hardirq.h
@@ -18,13 +18,6 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <asm/lowcore.h> 19#include <asm/lowcore.h>
20 20
21/* irq_cpustat_t is unused currently, but could be converted
22 * into a percpu variable instead of storing softirq_pending
23 * on the lowcore */
24typedef struct {
25 unsigned int __softirq_pending;
26} irq_cpustat_t;
27
28#define local_softirq_pending() (S390_lowcore.softirq_pending) 21#define local_softirq_pending() (S390_lowcore.softirq_pending)
29 22
30#define __ARCH_IRQ_STAT 23#define __ARCH_IRQ_STAT
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index 1171e6d144a3..5e95d95450b3 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -57,6 +57,8 @@ struct ipl_block_fcp {
57} __attribute__((packed)); 57} __attribute__((packed));
58 58
59#define DIAG308_VMPARM_SIZE 64 59#define DIAG308_VMPARM_SIZE 64
60#define DIAG308_SCPDATA_SIZE (PAGE_SIZE - (sizeof(struct ipl_list_hdr) + \
61 offsetof(struct ipl_block_fcp, scp_data)))
60 62
61struct ipl_block_ccw { 63struct ipl_block_ccw {
62 u8 load_parm[8]; 64 u8 load_parm[8];
@@ -91,7 +93,8 @@ extern void do_halt(void);
91extern void do_poff(void); 93extern void do_poff(void);
92extern void ipl_save_parameters(void); 94extern void ipl_save_parameters(void);
93extern void ipl_update_parameters(void); 95extern void ipl_update_parameters(void);
94extern void get_ipl_vmparm(char *); 96extern size_t append_ipl_vmparm(char *, size_t);
97extern size_t append_ipl_scpdata(char *, size_t);
95 98
96enum { 99enum {
97 IPL_DEVNO_VALID = 1, 100 IPL_DEVNO_VALID = 1,
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index 0b2f829f6d50..3dfcaeb5d7f4 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -15,15 +15,6 @@
15 */ 15 */
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
19struct kvm_pic_state {
20 /* no PIC for s390 */
21};
22
23struct kvm_ioapic_state {
24 /* no IOAPIC for s390 */
25};
26
27/* for KVM_GET_REGS and KVM_SET_REGS */ 18/* for KVM_GET_REGS and KVM_SET_REGS */
28struct kvm_regs { 19struct kvm_regs {
29 /* general purpose regs for s390 */ 20 /* general purpose regs for s390 */
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 1cd02f6073a0..27605b62b980 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * asm-s390/kvm_host.h - definition for kernel virtual machines on s390 2 * asm-s390/kvm_host.h - definition for kernel virtual machines on s390
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2009
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -17,7 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/kvm_host.h> 18#include <linux/kvm_host.h>
19#include <asm/debug.h> 19#include <asm/debug.h>
20#include <asm/cpuid.h> 20#include <asm/cpu.h>
21 21
22#define KVM_MAX_VCPUS 64 22#define KVM_MAX_VCPUS 64
23#define KVM_MEMORY_SLOTS 32 23#define KVM_MEMORY_SLOTS 32
@@ -40,7 +40,11 @@ struct sca_block {
40 struct sca_entry cpu[64]; 40 struct sca_entry cpu[64];
41} __attribute__((packed)); 41} __attribute__((packed));
42 42
43#define KVM_PAGES_PER_HPAGE 256 43#define KVM_NR_PAGE_SIZES 2
44#define KVM_HPAGE_SHIFT(x) (PAGE_SHIFT + ((x) - 1) * 8)
45#define KVM_HPAGE_SIZE(x) (1UL << KVM_HPAGE_SHIFT(x))
46#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1))
47#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
44 48
45#define CPUSTAT_HOST 0x80000000 49#define CPUSTAT_HOST 0x80000000
46#define CPUSTAT_WAIT 0x10000000 50#define CPUSTAT_WAIT 0x10000000
@@ -182,8 +186,9 @@ struct kvm_s390_interrupt_info {
182}; 186};
183 187
184/* for local_interrupt.action_flags */ 188/* for local_interrupt.action_flags */
185#define ACTION_STORE_ON_STOP 1 189#define ACTION_STORE_ON_STOP (1<<0)
186#define ACTION_STOP_ON_STOP 2 190#define ACTION_STOP_ON_STOP (1<<1)
191#define ACTION_RELOADVCPU_ON_STOP (1<<2)
187 192
188struct kvm_s390_local_interrupt { 193struct kvm_s390_local_interrupt {
189 spinlock_t lock; 194 spinlock_t lock;
@@ -217,8 +222,8 @@ struct kvm_vcpu_arch {
217 struct hrtimer ckc_timer; 222 struct hrtimer ckc_timer;
218 struct tasklet_struct tasklet; 223 struct tasklet_struct tasklet;
219 union { 224 union {
220 cpuid_t cpu_id; 225 struct cpuid cpu_id;
221 u64 stidp_data; 226 u64 stidp_data;
222 }; 227 };
223}; 228};
224 229
@@ -227,8 +232,6 @@ struct kvm_vm_stat {
227}; 232};
228 233
229struct kvm_arch{ 234struct kvm_arch{
230 unsigned long guest_origin;
231 unsigned long guest_memsize;
232 struct sca_block *sca; 235 struct sca_block *sca;
233 debug_info_t *dbf; 236 debug_info_t *dbf;
234 struct kvm_s390_float_interrupt float_int; 237 struct kvm_s390_float_interrupt float_int;
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index 2c503796b619..6964db226f83 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -13,6 +13,8 @@
13#ifndef __S390_KVM_PARA_H 13#ifndef __S390_KVM_PARA_H
14#define __S390_KVM_PARA_H 14#define __S390_KVM_PARA_H
15 15
16#ifdef __KERNEL__
17
16/* 18/*
17 * Hypercalls for KVM on s390. The calling convention is similar to the 19 * Hypercalls for KVM on s390. The calling convention is similar to the
18 * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1 20 * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1
@@ -147,4 +149,6 @@ static inline unsigned int kvm_arch_para_features(void)
147 return 0; 149 return 0;
148} 150}
149 151
152#endif
153
150#endif /* __S390_KVM_PARA_H */ 154#endif /* __S390_KVM_PARA_H */
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h
index 0503936f101f..acdfdff26611 100644
--- a/arch/s390/include/asm/kvm_virtio.h
+++ b/arch/s390/include/asm/kvm_virtio.h
@@ -54,14 +54,4 @@ struct kvm_vqconfig {
54 * This is pagesize for historical reasons. */ 54 * This is pagesize for historical reasons. */
55#define KVM_S390_VIRTIO_RING_ALIGN 4096 55#define KVM_S390_VIRTIO_RING_ALIGN 4096
56 56
57#ifdef __KERNEL__
58/* early virtio console setup */
59#ifdef CONFIG_S390_GUEST
60extern void s390_virtio_console_init(void);
61#else
62static inline void s390_virtio_console_init(void)
63{
64}
65#endif /* CONFIG_VIRTIO_CONSOLE */
66#endif /* __KERNEL__ */
67#endif 57#endif
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 5046ad6b7a63..6bc9426a6fbf 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -132,7 +132,7 @@
132 132
133#ifndef __ASSEMBLY__ 133#ifndef __ASSEMBLY__
134 134
135#include <asm/cpuid.h> 135#include <asm/cpu.h>
136#include <asm/ptrace.h> 136#include <asm/ptrace.h>
137#include <linux/types.h> 137#include <linux/types.h>
138 138
@@ -275,7 +275,7 @@ struct _lowcore
275 __u32 user_exec_asce; /* 0x02ac */ 275 __u32 user_exec_asce; /* 0x02ac */
276 276
277 /* SMP info area */ 277 /* SMP info area */
278 cpuid_t cpu_id; /* 0x02b0 */ 278 struct cpuid cpu_id; /* 0x02b0 */
279 __u32 cpu_nr; /* 0x02b8 */ 279 __u32 cpu_nr; /* 0x02b8 */
280 __u32 softirq_pending; /* 0x02bc */ 280 __u32 softirq_pending; /* 0x02bc */
281 __u32 percpu_offset; /* 0x02c0 */ 281 __u32 percpu_offset; /* 0x02c0 */
@@ -380,7 +380,7 @@ struct _lowcore
380 __u64 user_exec_asce; /* 0x0318 */ 380 __u64 user_exec_asce; /* 0x0318 */
381 381
382 /* SMP info area */ 382 /* SMP info area */
383 cpuid_t cpu_id; /* 0x0320 */ 383 struct cpuid cpu_id; /* 0x0320 */
384 __u32 cpu_nr; /* 0x0328 */ 384 __u32 cpu_nr; /* 0x0328 */
385 __u32 softirq_pending; /* 0x032c */ 385 __u32 softirq_pending; /* 0x032c */
386 __u64 percpu_offset; /* 0x0330 */ 386 __u64 percpu_offset; /* 0x0330 */
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h
index 3b59216e6284..03be99919d62 100644
--- a/arch/s390/include/asm/mmu.h
+++ b/arch/s390/include/asm/mmu.h
@@ -2,6 +2,7 @@
2#define __MMU_H 2#define __MMU_H
3 3
4typedef struct { 4typedef struct {
5 spinlock_t list_lock;
5 struct list_head crst_list; 6 struct list_head crst_list;
6 struct list_head pgtable_list; 7 struct list_head pgtable_list;
7 unsigned long asce_bits; 8 unsigned long asce_bits;
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 3e3594d01f83..5e9daf5d7f22 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -125,8 +125,6 @@ page_get_storage_key(unsigned long addr)
125 return skey; 125 return skey;
126} 126}
127 127
128#ifdef CONFIG_PAGE_STATES
129
130struct page; 128struct page;
131void arch_free_page(struct page *page, int order); 129void arch_free_page(struct page *page, int order);
132void arch_alloc_page(struct page *page, int order); 130void arch_alloc_page(struct page *page, int order);
@@ -134,8 +132,6 @@ void arch_alloc_page(struct page *page, int order);
134#define HAVE_ARCH_FREE_PAGE 132#define HAVE_ARCH_FREE_PAGE
135#define HAVE_ARCH_ALLOC_PAGE 133#define HAVE_ARCH_ALLOC_PAGE
136 134
137#endif
138
139#endif /* !__ASSEMBLY__ */ 135#endif /* !__ASSEMBLY__ */
140 136
141#define __PAGE_OFFSET 0x0UL 137#define __PAGE_OFFSET 0x0UL
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index b2658b9220fe..ddad5903341c 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -140,6 +140,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
140 140
141static inline pgd_t *pgd_alloc(struct mm_struct *mm) 141static inline pgd_t *pgd_alloc(struct mm_struct *mm)
142{ 142{
143 spin_lock_init(&mm->context.list_lock);
143 INIT_LIST_HEAD(&mm->context.crst_list); 144 INIT_LIST_HEAD(&mm->context.crst_list);
144 INIT_LIST_HEAD(&mm->context.pgtable_list); 145 INIT_LIST_HEAD(&mm->context.pgtable_list);
145 return (pgd_t *) crst_table_alloc(mm, s390_noexec); 146 return (pgd_t *) crst_table_alloc(mm, s390_noexec);
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index c139fa7b8e89..cf8eed3fa779 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -14,7 +14,7 @@
14#define __ASM_S390_PROCESSOR_H 14#define __ASM_S390_PROCESSOR_H
15 15
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17#include <asm/cpuid.h> 17#include <asm/cpu.h>
18#include <asm/page.h> 18#include <asm/page.h>
19#include <asm/ptrace.h> 19#include <asm/ptrace.h>
20#include <asm/setup.h> 20#include <asm/setup.h>
@@ -26,7 +26,7 @@
26 */ 26 */
27#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) 27#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; })
28 28
29static inline void get_cpu_id(cpuid_t *ptr) 29static inline void get_cpu_id(struct cpuid *ptr)
30{ 30{
31 asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); 31 asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
32} 32}
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h
index 29ec8e28c8df..35d786fe93ae 100644
--- a/arch/s390/include/asm/scatterlist.h
+++ b/arch/s390/include/asm/scatterlist.h
@@ -1,19 +1 @@
1#ifndef _ASMS390_SCATTERLIST_H #include <asm-generic/scatterlist.h>
2#define _ASMS390_SCATTERLIST_H
3
4struct scatterlist {
5#ifdef CONFIG_DEBUG_SG
6 unsigned long sg_magic;
7#endif
8 unsigned long page_link;
9 unsigned int offset;
10 unsigned int length;
11};
12
13#ifdef __s390x__
14#define ISA_DMA_THRESHOLD (0xffffffffffffffffUL)
15#else
16#define ISA_DMA_THRESHOLD (0xffffffffUL)
17#endif
18
19#endif /* _ASMS390X_SCATTERLIST_H */
diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h
new file mode 100644
index 000000000000..de389cb54d28
--- /dev/null
+++ b/arch/s390/include/asm/scsw.h
@@ -0,0 +1,956 @@
1/*
2 * Helper functions for scsw access.
3 *
4 * Copyright IBM Corp. 2008,2009
5 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 */
7
8#ifndef _ASM_S390_SCSW_H_
9#define _ASM_S390_SCSW_H_
10
11#include <linux/types.h>
12#include <asm/chsc.h>
13#include <asm/cio.h>
14
15/**
16 * struct cmd_scsw - command-mode subchannel status word
17 * @key: subchannel key
18 * @sctl: suspend control
19 * @eswf: esw format
20 * @cc: deferred condition code
21 * @fmt: format
22 * @pfch: prefetch
23 * @isic: initial-status interruption control
24 * @alcc: address-limit checking control
25 * @ssi: suppress-suspended interruption
26 * @zcc: zero condition code
27 * @ectl: extended control
28 * @pno: path not operational
29 * @res: reserved
30 * @fctl: function control
31 * @actl: activity control
32 * @stctl: status control
33 * @cpa: channel program address
34 * @dstat: device status
35 * @cstat: subchannel status
36 * @count: residual count
37 */
38struct cmd_scsw {
39 __u32 key : 4;
40 __u32 sctl : 1;
41 __u32 eswf : 1;
42 __u32 cc : 2;
43 __u32 fmt : 1;
44 __u32 pfch : 1;
45 __u32 isic : 1;
46 __u32 alcc : 1;
47 __u32 ssi : 1;
48 __u32 zcc : 1;
49 __u32 ectl : 1;
50 __u32 pno : 1;
51 __u32 res : 1;
52 __u32 fctl : 3;
53 __u32 actl : 7;
54 __u32 stctl : 5;
55 __u32 cpa;
56 __u32 dstat : 8;
57 __u32 cstat : 8;
58 __u32 count : 16;
59} __attribute__ ((packed));
60
61/**
62 * struct tm_scsw - transport-mode subchannel status word
63 * @key: subchannel key
64 * @eswf: esw format
65 * @cc: deferred condition code
66 * @fmt: format
67 * @x: IRB-format control
68 * @q: interrogate-complete
69 * @ectl: extended control
70 * @pno: path not operational
71 * @fctl: function control
72 * @actl: activity control
73 * @stctl: status control
74 * @tcw: TCW address
75 * @dstat: device status
76 * @cstat: subchannel status
77 * @fcxs: FCX status
78 * @schxs: subchannel-extended status
79 */
80struct tm_scsw {
81 u32 key:4;
82 u32 :1;
83 u32 eswf:1;
84 u32 cc:2;
85 u32 fmt:3;
86 u32 x:1;
87 u32 q:1;
88 u32 :1;
89 u32 ectl:1;
90 u32 pno:1;
91 u32 :1;
92 u32 fctl:3;
93 u32 actl:7;
94 u32 stctl:5;
95 u32 tcw;
96 u32 dstat:8;
97 u32 cstat:8;
98 u32 fcxs:8;
99 u32 schxs:8;
100} __attribute__ ((packed));
101
102/**
103 * union scsw - subchannel status word
104 * @cmd: command-mode SCSW
105 * @tm: transport-mode SCSW
106 */
107union scsw {
108 struct cmd_scsw cmd;
109 struct tm_scsw tm;
110} __attribute__ ((packed));
111
112#define SCSW_FCTL_CLEAR_FUNC 0x1
113#define SCSW_FCTL_HALT_FUNC 0x2
114#define SCSW_FCTL_START_FUNC 0x4
115
116#define SCSW_ACTL_SUSPENDED 0x1
117#define SCSW_ACTL_DEVACT 0x2
118#define SCSW_ACTL_SCHACT 0x4
119#define SCSW_ACTL_CLEAR_PEND 0x8
120#define SCSW_ACTL_HALT_PEND 0x10
121#define SCSW_ACTL_START_PEND 0x20
122#define SCSW_ACTL_RESUME_PEND 0x40
123
124#define SCSW_STCTL_STATUS_PEND 0x1
125#define SCSW_STCTL_SEC_STATUS 0x2
126#define SCSW_STCTL_PRIM_STATUS 0x4
127#define SCSW_STCTL_INTER_STATUS 0x8
128#define SCSW_STCTL_ALERT_STATUS 0x10
129
130#define DEV_STAT_ATTENTION 0x80
131#define DEV_STAT_STAT_MOD 0x40
132#define DEV_STAT_CU_END 0x20
133#define DEV_STAT_BUSY 0x10
134#define DEV_STAT_CHN_END 0x08
135#define DEV_STAT_DEV_END 0x04
136#define DEV_STAT_UNIT_CHECK 0x02
137#define DEV_STAT_UNIT_EXCEP 0x01
138
139#define SCHN_STAT_PCI 0x80
140#define SCHN_STAT_INCORR_LEN 0x40
141#define SCHN_STAT_PROG_CHECK 0x20
142#define SCHN_STAT_PROT_CHECK 0x10
143#define SCHN_STAT_CHN_DATA_CHK 0x08
144#define SCHN_STAT_CHN_CTRL_CHK 0x04
145#define SCHN_STAT_INTF_CTRL_CHK 0x02
146#define SCHN_STAT_CHAIN_CHECK 0x01
147
148/*
149 * architectured values for first sense byte
150 */
151#define SNS0_CMD_REJECT 0x80
152#define SNS_CMD_REJECT SNS0_CMD_REJEC
153#define SNS0_INTERVENTION_REQ 0x40
154#define SNS0_BUS_OUT_CHECK 0x20
155#define SNS0_EQUIPMENT_CHECK 0x10
156#define SNS0_DATA_CHECK 0x08
157#define SNS0_OVERRUN 0x04
158#define SNS0_INCOMPL_DOMAIN 0x01
159
160/*
161 * architectured values for second sense byte
162 */
163#define SNS1_PERM_ERR 0x80
164#define SNS1_INV_TRACK_FORMAT 0x40
165#define SNS1_EOC 0x20
166#define SNS1_MESSAGE_TO_OPER 0x10
167#define SNS1_NO_REC_FOUND 0x08
168#define SNS1_FILE_PROTECTED 0x04
169#define SNS1_WRITE_INHIBITED 0x02
170#define SNS1_INPRECISE_END 0x01
171
172/*
173 * architectured values for third sense byte
174 */
175#define SNS2_REQ_INH_WRITE 0x80
176#define SNS2_CORRECTABLE 0x40
177#define SNS2_FIRST_LOG_ERR 0x20
178#define SNS2_ENV_DATA_PRESENT 0x10
179#define SNS2_INPRECISE_END 0x04
180
181/**
182 * scsw_is_tm - check for transport mode scsw
183 * @scsw: pointer to scsw
184 *
185 * Return non-zero if the specified scsw is a transport mode scsw, zero
186 * otherwise.
187 */
188static inline int scsw_is_tm(union scsw *scsw)
189{
190 return css_general_characteristics.fcx && (scsw->tm.x == 1);
191}
192
193/**
194 * scsw_key - return scsw key field
195 * @scsw: pointer to scsw
196 *
197 * Return the value of the key field of the specified scsw, regardless of
198 * whether it is a transport mode or command mode scsw.
199 */
200static inline u32 scsw_key(union scsw *scsw)
201{
202 if (scsw_is_tm(scsw))
203 return scsw->tm.key;
204 else
205 return scsw->cmd.key;
206}
207
208/**
209 * scsw_eswf - return scsw eswf field
210 * @scsw: pointer to scsw
211 *
212 * Return the value of the eswf field of the specified scsw, regardless of
213 * whether it is a transport mode or command mode scsw.
214 */
215static inline u32 scsw_eswf(union scsw *scsw)
216{
217 if (scsw_is_tm(scsw))
218 return scsw->tm.eswf;
219 else
220 return scsw->cmd.eswf;
221}
222
223/**
224 * scsw_cc - return scsw cc field
225 * @scsw: pointer to scsw
226 *
227 * Return the value of the cc field of the specified scsw, regardless of
228 * whether it is a transport mode or command mode scsw.
229 */
230static inline u32 scsw_cc(union scsw *scsw)
231{
232 if (scsw_is_tm(scsw))
233 return scsw->tm.cc;
234 else
235 return scsw->cmd.cc;
236}
237
238/**
239 * scsw_ectl - return scsw ectl field
240 * @scsw: pointer to scsw
241 *
242 * Return the value of the ectl field of the specified scsw, regardless of
243 * whether it is a transport mode or command mode scsw.
244 */
245static inline u32 scsw_ectl(union scsw *scsw)
246{
247 if (scsw_is_tm(scsw))
248 return scsw->tm.ectl;
249 else
250 return scsw->cmd.ectl;
251}
252
253/**
254 * scsw_pno - return scsw pno field
255 * @scsw: pointer to scsw
256 *
257 * Return the value of the pno field of the specified scsw, regardless of
258 * whether it is a transport mode or command mode scsw.
259 */
260static inline u32 scsw_pno(union scsw *scsw)
261{
262 if (scsw_is_tm(scsw))
263 return scsw->tm.pno;
264 else
265 return scsw->cmd.pno;
266}
267
268/**
269 * scsw_fctl - return scsw fctl field
270 * @scsw: pointer to scsw
271 *
272 * Return the value of the fctl field of the specified scsw, regardless of
273 * whether it is a transport mode or command mode scsw.
274 */
275static inline u32 scsw_fctl(union scsw *scsw)
276{
277 if (scsw_is_tm(scsw))
278 return scsw->tm.fctl;
279 else
280 return scsw->cmd.fctl;
281}
282
283/**
284 * scsw_actl - return scsw actl field
285 * @scsw: pointer to scsw
286 *
287 * Return the value of the actl field of the specified scsw, regardless of
288 * whether it is a transport mode or command mode scsw.
289 */
290static inline u32 scsw_actl(union scsw *scsw)
291{
292 if (scsw_is_tm(scsw))
293 return scsw->tm.actl;
294 else
295 return scsw->cmd.actl;
296}
297
298/**
299 * scsw_stctl - return scsw stctl field
300 * @scsw: pointer to scsw
301 *
302 * Return the value of the stctl field of the specified scsw, regardless of
303 * whether it is a transport mode or command mode scsw.
304 */
305static inline u32 scsw_stctl(union scsw *scsw)
306{
307 if (scsw_is_tm(scsw))
308 return scsw->tm.stctl;
309 else
310 return scsw->cmd.stctl;
311}
312
313/**
314 * scsw_dstat - return scsw dstat field
315 * @scsw: pointer to scsw
316 *
317 * Return the value of the dstat field of the specified scsw, regardless of
318 * whether it is a transport mode or command mode scsw.
319 */
320static inline u32 scsw_dstat(union scsw *scsw)
321{
322 if (scsw_is_tm(scsw))
323 return scsw->tm.dstat;
324 else
325 return scsw->cmd.dstat;
326}
327
328/**
329 * scsw_cstat - return scsw cstat field
330 * @scsw: pointer to scsw
331 *
332 * Return the value of the cstat field of the specified scsw, regardless of
333 * whether it is a transport mode or command mode scsw.
334 */
335static inline u32 scsw_cstat(union scsw *scsw)
336{
337 if (scsw_is_tm(scsw))
338 return scsw->tm.cstat;
339 else
340 return scsw->cmd.cstat;
341}
342
343/**
344 * scsw_cmd_is_valid_key - check key field validity
345 * @scsw: pointer to scsw
346 *
347 * Return non-zero if the key field of the specified command mode scsw is
348 * valid, zero otherwise.
349 */
350static inline int scsw_cmd_is_valid_key(union scsw *scsw)
351{
352 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
353}
354
355/**
356 * scsw_cmd_is_valid_sctl - check fctl field validity
357 * @scsw: pointer to scsw
358 *
359 * Return non-zero if the fctl field of the specified command mode scsw is
360 * valid, zero otherwise.
361 */
362static inline int scsw_cmd_is_valid_sctl(union scsw *scsw)
363{
364 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
365}
366
367/**
368 * scsw_cmd_is_valid_eswf - check eswf field validity
369 * @scsw: pointer to scsw
370 *
371 * Return non-zero if the eswf field of the specified command mode scsw is
372 * valid, zero otherwise.
373 */
374static inline int scsw_cmd_is_valid_eswf(union scsw *scsw)
375{
376 return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND);
377}
378
379/**
380 * scsw_cmd_is_valid_cc - check cc field validity
381 * @scsw: pointer to scsw
382 *
383 * Return non-zero if the cc field of the specified command mode scsw is
384 * valid, zero otherwise.
385 */
386static inline int scsw_cmd_is_valid_cc(union scsw *scsw)
387{
388 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) &&
389 (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND);
390}
391
392/**
393 * scsw_cmd_is_valid_fmt - check fmt field validity
394 * @scsw: pointer to scsw
395 *
396 * Return non-zero if the fmt field of the specified command mode scsw is
397 * valid, zero otherwise.
398 */
399static inline int scsw_cmd_is_valid_fmt(union scsw *scsw)
400{
401 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
402}
403
404/**
405 * scsw_cmd_is_valid_pfch - check pfch field validity
406 * @scsw: pointer to scsw
407 *
408 * Return non-zero if the pfch field of the specified command mode scsw is
409 * valid, zero otherwise.
410 */
411static inline int scsw_cmd_is_valid_pfch(union scsw *scsw)
412{
413 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
414}
415
416/**
417 * scsw_cmd_is_valid_isic - check isic field validity
418 * @scsw: pointer to scsw
419 *
420 * Return non-zero if the isic field of the specified command mode scsw is
421 * valid, zero otherwise.
422 */
423static inline int scsw_cmd_is_valid_isic(union scsw *scsw)
424{
425 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
426}
427
428/**
429 * scsw_cmd_is_valid_alcc - check alcc field validity
430 * @scsw: pointer to scsw
431 *
432 * Return non-zero if the alcc field of the specified command mode scsw is
433 * valid, zero otherwise.
434 */
435static inline int scsw_cmd_is_valid_alcc(union scsw *scsw)
436{
437 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
438}
439
440/**
441 * scsw_cmd_is_valid_ssi - check ssi field validity
442 * @scsw: pointer to scsw
443 *
444 * Return non-zero if the ssi field of the specified command mode scsw is
445 * valid, zero otherwise.
446 */
447static inline int scsw_cmd_is_valid_ssi(union scsw *scsw)
448{
449 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC);
450}
451
452/**
453 * scsw_cmd_is_valid_zcc - check zcc field validity
454 * @scsw: pointer to scsw
455 *
456 * Return non-zero if the zcc field of the specified command mode scsw is
457 * valid, zero otherwise.
458 */
459static inline int scsw_cmd_is_valid_zcc(union scsw *scsw)
460{
461 return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) &&
462 (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS);
463}
464
465/**
466 * scsw_cmd_is_valid_ectl - check ectl field validity
467 * @scsw: pointer to scsw
468 *
469 * Return non-zero if the ectl field of the specified command mode scsw is
470 * valid, zero otherwise.
471 */
472static inline int scsw_cmd_is_valid_ectl(union scsw *scsw)
473{
474 return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) &&
475 !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) &&
476 (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS);
477}
478
479/**
480 * scsw_cmd_is_valid_pno - check pno field validity
481 * @scsw: pointer to scsw
482 *
483 * Return non-zero if the pno field of the specified command mode scsw is
484 * valid, zero otherwise.
485 */
486static inline int scsw_cmd_is_valid_pno(union scsw *scsw)
487{
488 return (scsw->cmd.fctl != 0) &&
489 (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) &&
490 (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) ||
491 ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) &&
492 (scsw->cmd.actl & SCSW_ACTL_SUSPENDED)));
493}
494
495/**
496 * scsw_cmd_is_valid_fctl - check fctl field validity
497 * @scsw: pointer to scsw
498 *
499 * Return non-zero if the fctl field of the specified command mode scsw is
500 * valid, zero otherwise.
501 */
502static inline int scsw_cmd_is_valid_fctl(union scsw *scsw)
503{
504 /* Only valid if pmcw.dnv == 1*/
505 return 1;
506}
507
508/**
509 * scsw_cmd_is_valid_actl - check actl field validity
510 * @scsw: pointer to scsw
511 *
512 * Return non-zero if the actl field of the specified command mode scsw is
513 * valid, zero otherwise.
514 */
515static inline int scsw_cmd_is_valid_actl(union scsw *scsw)
516{
517 /* Only valid if pmcw.dnv == 1*/
518 return 1;
519}
520
521/**
522 * scsw_cmd_is_valid_stctl - check stctl field validity
523 * @scsw: pointer to scsw
524 *
525 * Return non-zero if the stctl field of the specified command mode scsw is
526 * valid, zero otherwise.
527 */
528static inline int scsw_cmd_is_valid_stctl(union scsw *scsw)
529{
530 /* Only valid if pmcw.dnv == 1*/
531 return 1;
532}
533
534/**
535 * scsw_cmd_is_valid_dstat - check dstat field validity
536 * @scsw: pointer to scsw
537 *
538 * Return non-zero if the dstat field of the specified command mode scsw is
539 * valid, zero otherwise.
540 */
541static inline int scsw_cmd_is_valid_dstat(union scsw *scsw)
542{
543 return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) &&
544 (scsw->cmd.cc != 3);
545}
546
547/**
548 * scsw_cmd_is_valid_cstat - check cstat field validity
549 * @scsw: pointer to scsw
550 *
551 * Return non-zero if the cstat field of the specified command mode scsw is
552 * valid, zero otherwise.
553 */
554static inline int scsw_cmd_is_valid_cstat(union scsw *scsw)
555{
556 return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) &&
557 (scsw->cmd.cc != 3);
558}
559
560/**
561 * scsw_tm_is_valid_key - check key field validity
562 * @scsw: pointer to scsw
563 *
564 * Return non-zero if the key field of the specified transport mode scsw is
565 * valid, zero otherwise.
566 */
567static inline int scsw_tm_is_valid_key(union scsw *scsw)
568{
569 return (scsw->tm.fctl & SCSW_FCTL_START_FUNC);
570}
571
572/**
573 * scsw_tm_is_valid_eswf - check eswf field validity
574 * @scsw: pointer to scsw
575 *
576 * Return non-zero if the eswf field of the specified transport mode scsw is
577 * valid, zero otherwise.
578 */
579static inline int scsw_tm_is_valid_eswf(union scsw *scsw)
580{
581 return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND);
582}
583
584/**
585 * scsw_tm_is_valid_cc - check cc field validity
586 * @scsw: pointer to scsw
587 *
588 * Return non-zero if the cc field of the specified transport mode scsw is
589 * valid, zero otherwise.
590 */
591static inline int scsw_tm_is_valid_cc(union scsw *scsw)
592{
593 return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) &&
594 (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND);
595}
596
597/**
598 * scsw_tm_is_valid_fmt - check fmt field validity
599 * @scsw: pointer to scsw
600 *
601 * Return non-zero if the fmt field of the specified transport mode scsw is
602 * valid, zero otherwise.
603 */
604static inline int scsw_tm_is_valid_fmt(union scsw *scsw)
605{
606 return 1;
607}
608
609/**
610 * scsw_tm_is_valid_x - check x field validity
611 * @scsw: pointer to scsw
612 *
613 * Return non-zero if the x field of the specified transport mode scsw is
614 * valid, zero otherwise.
615 */
616static inline int scsw_tm_is_valid_x(union scsw *scsw)
617{
618 return 1;
619}
620
621/**
622 * scsw_tm_is_valid_q - check q field validity
623 * @scsw: pointer to scsw
624 *
625 * Return non-zero if the q field of the specified transport mode scsw is
626 * valid, zero otherwise.
627 */
628static inline int scsw_tm_is_valid_q(union scsw *scsw)
629{
630 return 1;
631}
632
633/**
634 * scsw_tm_is_valid_ectl - check ectl field validity
635 * @scsw: pointer to scsw
636 *
637 * Return non-zero if the ectl field of the specified transport mode scsw is
638 * valid, zero otherwise.
639 */
640static inline int scsw_tm_is_valid_ectl(union scsw *scsw)
641{
642 return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) &&
643 !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) &&
644 (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS);
645}
646
647/**
648 * scsw_tm_is_valid_pno - check pno field validity
649 * @scsw: pointer to scsw
650 *
651 * Return non-zero if the pno field of the specified transport mode scsw is
652 * valid, zero otherwise.
653 */
654static inline int scsw_tm_is_valid_pno(union scsw *scsw)
655{
656 return (scsw->tm.fctl != 0) &&
657 (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) &&
658 (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) ||
659 ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) &&
660 (scsw->tm.actl & SCSW_ACTL_SUSPENDED)));
661}
662
663/**
664 * scsw_tm_is_valid_fctl - check fctl field validity
665 * @scsw: pointer to scsw
666 *
667 * Return non-zero if the fctl field of the specified transport mode scsw is
668 * valid, zero otherwise.
669 */
670static inline int scsw_tm_is_valid_fctl(union scsw *scsw)
671{
672 /* Only valid if pmcw.dnv == 1*/
673 return 1;
674}
675
676/**
677 * scsw_tm_is_valid_actl - check actl field validity
678 * @scsw: pointer to scsw
679 *
680 * Return non-zero if the actl field of the specified transport mode scsw is
681 * valid, zero otherwise.
682 */
683static inline int scsw_tm_is_valid_actl(union scsw *scsw)
684{
685 /* Only valid if pmcw.dnv == 1*/
686 return 1;
687}
688
689/**
690 * scsw_tm_is_valid_stctl - check stctl field validity
691 * @scsw: pointer to scsw
692 *
693 * Return non-zero if the stctl field of the specified transport mode scsw is
694 * valid, zero otherwise.
695 */
696static inline int scsw_tm_is_valid_stctl(union scsw *scsw)
697{
698 /* Only valid if pmcw.dnv == 1*/
699 return 1;
700}
701
702/**
703 * scsw_tm_is_valid_dstat - check dstat field validity
704 * @scsw: pointer to scsw
705 *
706 * Return non-zero if the dstat field of the specified transport mode scsw is
707 * valid, zero otherwise.
708 */
709static inline int scsw_tm_is_valid_dstat(union scsw *scsw)
710{
711 return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) &&
712 (scsw->tm.cc != 3);
713}
714
715/**
716 * scsw_tm_is_valid_cstat - check cstat field validity
717 * @scsw: pointer to scsw
718 *
719 * Return non-zero if the cstat field of the specified transport mode scsw is
720 * valid, zero otherwise.
721 */
722static inline int scsw_tm_is_valid_cstat(union scsw *scsw)
723{
724 return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) &&
725 (scsw->tm.cc != 3);
726}
727
728/**
729 * scsw_tm_is_valid_fcxs - check fcxs field validity
730 * @scsw: pointer to scsw
731 *
732 * Return non-zero if the fcxs field of the specified transport mode scsw is
733 * valid, zero otherwise.
734 */
735static inline int scsw_tm_is_valid_fcxs(union scsw *scsw)
736{
737 return 1;
738}
739
740/**
741 * scsw_tm_is_valid_schxs - check schxs field validity
742 * @scsw: pointer to scsw
743 *
744 * Return non-zero if the schxs field of the specified transport mode scsw is
745 * valid, zero otherwise.
746 */
747static inline int scsw_tm_is_valid_schxs(union scsw *scsw)
748{
749 return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK |
750 SCHN_STAT_INTF_CTRL_CHK |
751 SCHN_STAT_PROT_CHECK |
752 SCHN_STAT_CHN_DATA_CHK));
753}
754
755/**
756 * scsw_is_valid_actl - check actl field validity
757 * @scsw: pointer to scsw
758 *
759 * Return non-zero if the actl field of the specified scsw is valid,
760 * regardless of whether it is a transport mode or command mode scsw.
761 * Return zero if the field does not contain a valid value.
762 */
763static inline int scsw_is_valid_actl(union scsw *scsw)
764{
765 if (scsw_is_tm(scsw))
766 return scsw_tm_is_valid_actl(scsw);
767 else
768 return scsw_cmd_is_valid_actl(scsw);
769}
770
771/**
772 * scsw_is_valid_cc - check cc field validity
773 * @scsw: pointer to scsw
774 *
775 * Return non-zero if the cc field of the specified scsw is valid,
776 * regardless of whether it is a transport mode or command mode scsw.
777 * Return zero if the field does not contain a valid value.
778 */
779static inline int scsw_is_valid_cc(union scsw *scsw)
780{
781 if (scsw_is_tm(scsw))
782 return scsw_tm_is_valid_cc(scsw);
783 else
784 return scsw_cmd_is_valid_cc(scsw);
785}
786
787/**
788 * scsw_is_valid_cstat - check cstat field validity
789 * @scsw: pointer to scsw
790 *
791 * Return non-zero if the cstat field of the specified scsw is valid,
792 * regardless of whether it is a transport mode or command mode scsw.
793 * Return zero if the field does not contain a valid value.
794 */
795static inline int scsw_is_valid_cstat(union scsw *scsw)
796{
797 if (scsw_is_tm(scsw))
798 return scsw_tm_is_valid_cstat(scsw);
799 else
800 return scsw_cmd_is_valid_cstat(scsw);
801}
802
803/**
804 * scsw_is_valid_dstat - check dstat field validity
805 * @scsw: pointer to scsw
806 *
807 * Return non-zero if the dstat field of the specified scsw is valid,
808 * regardless of whether it is a transport mode or command mode scsw.
809 * Return zero if the field does not contain a valid value.
810 */
811static inline int scsw_is_valid_dstat(union scsw *scsw)
812{
813 if (scsw_is_tm(scsw))
814 return scsw_tm_is_valid_dstat(scsw);
815 else
816 return scsw_cmd_is_valid_dstat(scsw);
817}
818
819/**
820 * scsw_is_valid_ectl - check ectl field validity
821 * @scsw: pointer to scsw
822 *
823 * Return non-zero if the ectl field of the specified scsw is valid,
824 * regardless of whether it is a transport mode or command mode scsw.
825 * Return zero if the field does not contain a valid value.
826 */
827static inline int scsw_is_valid_ectl(union scsw *scsw)
828{
829 if (scsw_is_tm(scsw))
830 return scsw_tm_is_valid_ectl(scsw);
831 else
832 return scsw_cmd_is_valid_ectl(scsw);
833}
834
835/**
836 * scsw_is_valid_eswf - check eswf field validity
837 * @scsw: pointer to scsw
838 *
839 * Return non-zero if the eswf field of the specified scsw is valid,
840 * regardless of whether it is a transport mode or command mode scsw.
841 * Return zero if the field does not contain a valid value.
842 */
843static inline int scsw_is_valid_eswf(union scsw *scsw)
844{
845 if (scsw_is_tm(scsw))
846 return scsw_tm_is_valid_eswf(scsw);
847 else
848 return scsw_cmd_is_valid_eswf(scsw);
849}
850
851/**
852 * scsw_is_valid_fctl - check fctl field validity
853 * @scsw: pointer to scsw
854 *
855 * Return non-zero if the fctl field of the specified scsw is valid,
856 * regardless of whether it is a transport mode or command mode scsw.
857 * Return zero if the field does not contain a valid value.
858 */
859static inline int scsw_is_valid_fctl(union scsw *scsw)
860{
861 if (scsw_is_tm(scsw))
862 return scsw_tm_is_valid_fctl(scsw);
863 else
864 return scsw_cmd_is_valid_fctl(scsw);
865}
866
867/**
868 * scsw_is_valid_key - check key field validity
869 * @scsw: pointer to scsw
870 *
871 * Return non-zero if the key field of the specified scsw is valid,
872 * regardless of whether it is a transport mode or command mode scsw.
873 * Return zero if the field does not contain a valid value.
874 */
875static inline int scsw_is_valid_key(union scsw *scsw)
876{
877 if (scsw_is_tm(scsw))
878 return scsw_tm_is_valid_key(scsw);
879 else
880 return scsw_cmd_is_valid_key(scsw);
881}
882
883/**
884 * scsw_is_valid_pno - check pno field validity
885 * @scsw: pointer to scsw
886 *
887 * Return non-zero if the pno field of the specified scsw is valid,
888 * regardless of whether it is a transport mode or command mode scsw.
889 * Return zero if the field does not contain a valid value.
890 */
891static inline int scsw_is_valid_pno(union scsw *scsw)
892{
893 if (scsw_is_tm(scsw))
894 return scsw_tm_is_valid_pno(scsw);
895 else
896 return scsw_cmd_is_valid_pno(scsw);
897}
898
899/**
900 * scsw_is_valid_stctl - check stctl field validity
901 * @scsw: pointer to scsw
902 *
903 * Return non-zero if the stctl field of the specified scsw is valid,
904 * regardless of whether it is a transport mode or command mode scsw.
905 * Return zero if the field does not contain a valid value.
906 */
907static inline int scsw_is_valid_stctl(union scsw *scsw)
908{
909 if (scsw_is_tm(scsw))
910 return scsw_tm_is_valid_stctl(scsw);
911 else
912 return scsw_cmd_is_valid_stctl(scsw);
913}
914
915/**
916 * scsw_cmd_is_solicited - check for solicited scsw
917 * @scsw: pointer to scsw
918 *
919 * Return non-zero if the command mode scsw indicates that the associated
920 * status condition is solicited, zero if it is unsolicited.
921 */
922static inline int scsw_cmd_is_solicited(union scsw *scsw)
923{
924 return (scsw->cmd.cc != 0) || (scsw->cmd.stctl !=
925 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS));
926}
927
928/**
929 * scsw_tm_is_solicited - check for solicited scsw
930 * @scsw: pointer to scsw
931 *
932 * Return non-zero if the transport mode scsw indicates that the associated
933 * status condition is solicited, zero if it is unsolicited.
934 */
935static inline int scsw_tm_is_solicited(union scsw *scsw)
936{
937 return (scsw->tm.cc != 0) || (scsw->tm.stctl !=
938 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS));
939}
940
941/**
942 * scsw_is_solicited - check for solicited scsw
943 * @scsw: pointer to scsw
944 *
945 * Return non-zero if the transport or command mode scsw indicates that the
946 * associated status condition is solicited, zero if it is unsolicited.
947 */
948static inline int scsw_is_solicited(union scsw *scsw)
949{
950 if (scsw_is_tm(scsw))
951 return scsw_tm_is_solicited(scsw);
952 else
953 return scsw_cmd_is_solicited(scsw);
954}
955
956#endif /* _ASM_S390_SCSW_H_ */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 38b0fc221ed7..e37478e87286 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -8,7 +8,7 @@
8#ifndef _ASM_S390_SETUP_H 8#ifndef _ASM_S390_SETUP_H
9#define _ASM_S390_SETUP_H 9#define _ASM_S390_SETUP_H
10 10
11#define COMMAND_LINE_SIZE 1024 11#define COMMAND_LINE_SIZE 4096
12 12
13#define ARCH_COMMAND_LINE_SIZE 896 13#define ARCH_COMMAND_LINE_SIZE 896
14 14
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 72137bc907ac..c991fe6473c9 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -51,32 +51,7 @@ extern void machine_power_off_smp(void);
51#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ 51#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */
52 52
53#define raw_smp_processor_id() (S390_lowcore.cpu_nr) 53#define raw_smp_processor_id() (S390_lowcore.cpu_nr)
54 54#define cpu_logical_map(cpu) (cpu)
55/*
56 * returns 1 if cpu is in stopped/check stopped state or not operational
57 * returns 0 otherwise
58 */
59static inline int
60smp_cpu_not_running(int cpu)
61{
62 __u32 status;
63
64 switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
65 case sigp_order_code_accepted:
66 case sigp_status_stored:
67 /* Check for stopped and check stop state */
68 if (status & 0x50)
69 return 1;
70 break;
71 case sigp_not_operational:
72 return 1;
73 default:
74 break;
75 }
76 return 0;
77}
78
79#define cpu_logical_map(cpu) (cpu)
80 55
81extern int __cpu_disable (void); 56extern int __cpu_disable (void);
82extern void __cpu_die (unsigned int cpu); 57extern void __cpu_die (unsigned int cpu);
@@ -91,11 +66,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask);
91 66
92#endif 67#endif
93 68
94#ifndef CONFIG_SMP
95#define hard_smp_processor_id() 0
96#define smp_cpu_not_running(cpu) 1
97#endif
98
99#ifdef CONFIG_HOTPLUG_CPU 69#ifdef CONFIG_HOTPLUG_CPU
100extern int smp_rescan_cpus(void); 70extern int smp_rescan_cpus(void);
101#else 71#else
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index 02330c50241b..e42df89a0b85 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -65,4 +65,7 @@
65#define SO_TIMESTAMPING 37 65#define SO_TIMESTAMPING 37
66#define SCM_TIMESTAMPING SO_TIMESTAMPING 66#define SCM_TIMESTAMPING SO_TIMESTAMPING
67 67
68#define SO_PROTOCOL 38
69#define SO_DOMAIN 39
70
68#endif /* _ASM_SOCKET_H */ 71#endif /* _ASM_SOCKET_H */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index c9af0d19c7ab..41ce6861174e 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -191,4 +191,33 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
191#define _raw_read_relax(lock) cpu_relax() 191#define _raw_read_relax(lock) cpu_relax()
192#define _raw_write_relax(lock) cpu_relax() 192#define _raw_write_relax(lock) cpu_relax()
193 193
194#define __always_inline__spin_lock
195#define __always_inline__read_lock
196#define __always_inline__write_lock
197#define __always_inline__spin_lock_bh
198#define __always_inline__read_lock_bh
199#define __always_inline__write_lock_bh
200#define __always_inline__spin_lock_irq
201#define __always_inline__read_lock_irq
202#define __always_inline__write_lock_irq
203#define __always_inline__spin_lock_irqsave
204#define __always_inline__read_lock_irqsave
205#define __always_inline__write_lock_irqsave
206#define __always_inline__spin_trylock
207#define __always_inline__read_trylock
208#define __always_inline__write_trylock
209#define __always_inline__spin_trylock_bh
210#define __always_inline__spin_unlock
211#define __always_inline__read_unlock
212#define __always_inline__write_unlock
213#define __always_inline__spin_unlock_bh
214#define __always_inline__read_unlock_bh
215#define __always_inline__write_unlock_bh
216#define __always_inline__spin_unlock_irq
217#define __always_inline__read_unlock_irq
218#define __always_inline__write_unlock_irq
219#define __always_inline__spin_unlock_irqrestore
220#define __always_inline__read_unlock_irqrestore
221#define __always_inline__write_unlock_irqrestore
222
194#endif /* __ASM_SPINLOCK_H */ 223#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index 4fb83c1cdb77..379661d2f81a 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -109,11 +109,7 @@ extern void pfault_fini(void);
109#define pfault_fini() do { } while (0) 109#define pfault_fini() do { } while (0)
110#endif /* CONFIG_PFAULT */ 110#endif /* CONFIG_PFAULT */
111 111
112#ifdef CONFIG_PAGE_STATES
113extern void cmma_init(void); 112extern void cmma_init(void);
114#else
115static inline void cmma_init(void) { }
116#endif
117 113
118#define finish_arch_switch(prev) do { \ 114#define finish_arch_switch(prev) do { \
119 set_fs(current->thread.mm_segment); \ 115 set_fs(current->thread.mm_segment); \
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
index cc21e3e20fd7..68d9fea34b4b 100644
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -88,6 +88,28 @@ int get_sync_clock(unsigned long long *clock);
88void init_cpu_timer(void); 88void init_cpu_timer(void);
89unsigned long long monotonic_clock(void); 89unsigned long long monotonic_clock(void);
90 90
91void tod_to_timeval(__u64, struct timespec *);
92
93static inline
94void stck_to_timespec(unsigned long long stck, struct timespec *ts)
95{
96 tod_to_timeval(stck - TOD_UNIX_EPOCH, ts);
97}
98
91extern u64 sched_clock_base_cc; 99extern u64 sched_clock_base_cc;
92 100
101/**
102 * get_clock_monotonic - returns current time in clock rate units
103 *
104 * The caller must ensure that preemption is disabled.
105 * The clock and sched_clock_base get changed via stop_machine.
106 * Therefore preemption must be disabled when calling this
107 * function, otherwise the returned value is not guaranteed to
108 * be monotonic.
109 */
110static inline unsigned long long get_clock_monotonic(void)
111{
112 return get_clock_xt() - sched_clock_base_cc;
113}
114
93#endif 115#endif
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index c75ed43b1a18..c7be8e10b87e 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -32,7 +32,7 @@ extra-y += head.o init_task.o vmlinux.lds
32 32
33obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 33obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
34obj-$(CONFIG_SMP) += smp.o topology.o 34obj-$(CONFIG_SMP) += smp.o topology.o
35 35obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
36obj-$(CONFIG_AUDIT) += audit.o 36obj-$(CONFIG_AUDIT) += audit.o
37compat-obj-$(CONFIG_AUDIT) += compat_audit.o 37compat-obj-$(CONFIG_AUDIT) += compat_audit.o
38obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ 38obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
@@ -41,7 +41,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
41 41
42obj-$(CONFIG_STACKTRACE) += stacktrace.o 42obj-$(CONFIG_STACKTRACE) += stacktrace.o
43obj-$(CONFIG_KPROBES) += kprobes.o 43obj-$(CONFIG_KPROBES) += kprobes.o
44obj-$(CONFIG_FUNCTION_TRACER) += mcount.o 44obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o)
45obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 45obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
46obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 46obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
47 47
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index be8bceaf37d9..4c512561687d 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -63,8 +63,6 @@ typedef struct
63} debug_sprintf_entry_t; 63} debug_sprintf_entry_t;
64 64
65 65
66extern void tod_to_timeval(uint64_t todval, struct timespec *xtime);
67
68/* internal function prototyes */ 66/* internal function prototyes */
69 67
70static int debug_init(void); 68static int debug_init(void);
@@ -1450,17 +1448,13 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
1450 int area, debug_entry_t * entry, char *out_buf) 1448 int area, debug_entry_t * entry, char *out_buf)
1451{ 1449{
1452 struct timespec time_spec; 1450 struct timespec time_spec;
1453 unsigned long long time;
1454 char *except_str; 1451 char *except_str;
1455 unsigned long caller; 1452 unsigned long caller;
1456 int rc = 0; 1453 int rc = 0;
1457 unsigned int level; 1454 unsigned int level;
1458 1455
1459 level = entry->id.fields.level; 1456 level = entry->id.fields.level;
1460 time = entry->id.stck; 1457 stck_to_timespec(entry->id.stck, &time_spec);
1461 /* adjust todclock to 1970 */
1462 time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
1463 tod_to_timeval(time, &time_spec);
1464 1458
1465 if (entry->id.fields.exception) 1459 if (entry->id.fields.exception)
1466 except_str = "*"; 1460 except_str = "*";
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index cae14c499511..bf8b4ae7ff2d 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -6,6 +6,9 @@
6 * Heiko Carstens <heiko.carstens@de.ibm.com> 6 * Heiko Carstens <heiko.carstens@de.ibm.com>
7 */ 7 */
8 8
9#define KMSG_COMPONENT "setup"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11
9#include <linux/compiler.h> 12#include <linux/compiler.h>
10#include <linux/init.h> 13#include <linux/init.h>
11#include <linux/errno.h> 14#include <linux/errno.h>
@@ -16,6 +19,7 @@
16#include <linux/module.h> 19#include <linux/module.h>
17#include <linux/pfn.h> 20#include <linux/pfn.h>
18#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/kernel.h>
19#include <asm/ebcdic.h> 23#include <asm/ebcdic.h>
20#include <asm/ipl.h> 24#include <asm/ipl.h>
21#include <asm/lowcore.h> 25#include <asm/lowcore.h>
@@ -35,8 +39,6 @@
35 39
36char kernel_nss_name[NSS_NAME_SIZE + 1]; 40char kernel_nss_name[NSS_NAME_SIZE + 1];
37 41
38static unsigned long machine_flags;
39
40static void __init setup_boot_command_line(void); 42static void __init setup_boot_command_line(void);
41 43
42/* 44/*
@@ -81,6 +83,8 @@ asm(
81 " br 14\n" 83 " br 14\n"
82 " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); 84 " .size savesys_ipl_nss, .-savesys_ipl_nss\n");
83 85
86static __initdata char upper_command_line[COMMAND_LINE_SIZE];
87
84static noinline __init void create_kernel_nss(void) 88static noinline __init void create_kernel_nss(void)
85{ 89{
86 unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; 90 unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size;
@@ -90,7 +94,6 @@ static noinline __init void create_kernel_nss(void)
90 int response; 94 int response;
91 size_t len; 95 size_t len;
92 char *savesys_ptr; 96 char *savesys_ptr;
93 char upper_command_line[COMMAND_LINE_SIZE];
94 char defsys_cmd[DEFSYS_CMD_SIZE]; 97 char defsys_cmd[DEFSYS_CMD_SIZE];
95 char savesys_cmd[SAVESYS_CMD_SIZE]; 98 char savesys_cmd[SAVESYS_CMD_SIZE];
96 99
@@ -141,6 +144,8 @@ static noinline __init void create_kernel_nss(void)
141 __cpcmd(defsys_cmd, NULL, 0, &response); 144 __cpcmd(defsys_cmd, NULL, 0, &response);
142 145
143 if (response != 0) { 146 if (response != 0) {
147 pr_err("Defining the Linux kernel NSS failed with rc=%d\n",
148 response);
144 kernel_nss_name[0] = '\0'; 149 kernel_nss_name[0] = '\0';
145 return; 150 return;
146 } 151 }
@@ -153,8 +158,11 @@ static noinline __init void create_kernel_nss(void)
153 * max SAVESYS_CMD_SIZE 158 * max SAVESYS_CMD_SIZE
154 * On error: response contains the numeric portion of cp error message. 159 * On error: response contains the numeric portion of cp error message.
155 * for SAVESYS it will be >= 263 160 * for SAVESYS it will be >= 263
161 * for missing privilege class, it will be 1
156 */ 162 */
157 if (response > SAVESYS_CMD_SIZE) { 163 if (response > SAVESYS_CMD_SIZE || response == 1) {
164 pr_err("Saving the Linux kernel NSS failed with rc=%d\n",
165 response);
158 kernel_nss_name[0] = '\0'; 166 kernel_nss_name[0] = '\0';
159 return; 167 return;
160 } 168 }
@@ -205,12 +213,9 @@ static noinline __init void detect_machine_type(void)
205 213
206 /* Running under KVM? If not we assume z/VM */ 214 /* Running under KVM? If not we assume z/VM */
207 if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) 215 if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3))
208 machine_flags |= MACHINE_FLAG_KVM; 216 S390_lowcore.machine_flags |= MACHINE_FLAG_KVM;
209 else 217 else
210 machine_flags |= MACHINE_FLAG_VM; 218 S390_lowcore.machine_flags |= MACHINE_FLAG_VM;
211
212 /* Store machine flags for setting up lowcore early */
213 S390_lowcore.machine_flags = machine_flags;
214} 219}
215 220
216static __init void early_pgm_check_handler(void) 221static __init void early_pgm_check_handler(void)
@@ -245,7 +250,7 @@ static noinline __init void setup_hpage(void)
245 facilities = stfl(); 250 facilities = stfl();
246 if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) 251 if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29)))
247 return; 252 return;
248 machine_flags |= MACHINE_FLAG_HPAGE; 253 S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
249 __ctl_set_bit(0, 23); 254 __ctl_set_bit(0, 23);
250#endif 255#endif
251} 256}
@@ -263,7 +268,7 @@ static __init void detect_mvpg(void)
263 EX_TABLE(0b,1b) 268 EX_TABLE(0b,1b)
264 : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); 269 : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0");
265 if (!rc) 270 if (!rc)
266 machine_flags |= MACHINE_FLAG_MVPG; 271 S390_lowcore.machine_flags |= MACHINE_FLAG_MVPG;
267#endif 272#endif
268} 273}
269 274
@@ -279,7 +284,7 @@ static __init void detect_ieee(void)
279 EX_TABLE(0b,1b) 284 EX_TABLE(0b,1b)
280 : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); 285 : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc");
281 if (!rc) 286 if (!rc)
282 machine_flags |= MACHINE_FLAG_IEEE; 287 S390_lowcore.machine_flags |= MACHINE_FLAG_IEEE;
283#endif 288#endif
284} 289}
285 290
@@ -298,7 +303,7 @@ static __init void detect_csp(void)
298 EX_TABLE(0b,1b) 303 EX_TABLE(0b,1b)
299 : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); 304 : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2");
300 if (!rc) 305 if (!rc)
301 machine_flags |= MACHINE_FLAG_CSP; 306 S390_lowcore.machine_flags |= MACHINE_FLAG_CSP;
302#endif 307#endif
303} 308}
304 309
@@ -315,7 +320,7 @@ static __init void detect_diag9c(void)
315 EX_TABLE(0b,1b) 320 EX_TABLE(0b,1b)
316 : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); 321 : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc");
317 if (!rc) 322 if (!rc)
318 machine_flags |= MACHINE_FLAG_DIAG9C; 323 S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C;
319} 324}
320 325
321static __init void detect_diag44(void) 326static __init void detect_diag44(void)
@@ -330,7 +335,7 @@ static __init void detect_diag44(void)
330 EX_TABLE(0b,1b) 335 EX_TABLE(0b,1b)
331 : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); 336 : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc");
332 if (!rc) 337 if (!rc)
333 machine_flags |= MACHINE_FLAG_DIAG44; 338 S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44;
334#endif 339#endif
335} 340}
336 341
@@ -341,11 +346,11 @@ static __init void detect_machine_facilities(void)
341 346
342 facilities = stfl(); 347 facilities = stfl();
343 if (facilities & (1 << 28)) 348 if (facilities & (1 << 28))
344 machine_flags |= MACHINE_FLAG_IDTE; 349 S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
345 if (facilities & (1 << 23)) 350 if (facilities & (1 << 23))
346 machine_flags |= MACHINE_FLAG_PFMF; 351 S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
347 if (facilities & (1 << 4)) 352 if (facilities & (1 << 4))
348 machine_flags |= MACHINE_FLAG_MVCOS; 353 S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
349#endif 354#endif
350} 355}
351 356
@@ -367,21 +372,35 @@ static __init void rescue_initrd(void)
367} 372}
368 373
369/* Set up boot command line */ 374/* Set up boot command line */
370static void __init setup_boot_command_line(void) 375static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
371{ 376{
372 char *parm = NULL; 377 char *parm, *delim;
378 size_t rc, len;
379
380 len = strlen(boot_command_line);
381
382 delim = boot_command_line + len; /* '\0' character position */
383 parm = boot_command_line + len + 1; /* append right after '\0' */
373 384
385 rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1);
386 if (rc) {
387 if (*parm == '=')
388 memmove(boot_command_line, parm + 1, rc);
389 else
390 *delim = ' '; /* replace '\0' with space */
391 }
392}
393
394static void __init setup_boot_command_line(void)
395{
374 /* copy arch command line */ 396 /* copy arch command line */
375 strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); 397 strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
376 398
377 /* append IPL PARM data to the boot command line */ 399 /* append IPL PARM data to the boot command line */
378 if (MACHINE_IS_VM) { 400 if (MACHINE_IS_VM)
379 parm = boot_command_line + strlen(boot_command_line); 401 append_to_cmdline(append_ipl_vmparm);
380 *parm++ = ' '; 402
381 get_ipl_vmparm(parm); 403 append_to_cmdline(append_ipl_scpdata);
382 if (parm[0] == '=')
383 memmove(boot_command_line, parm + 1, strlen(parm));
384 }
385} 404}
386 405
387 406
@@ -413,7 +432,6 @@ void __init startup_init(void)
413 setup_hpage(); 432 setup_hpage();
414 sclp_facilities_detect(); 433 sclp_facilities_detect();
415 detect_memory_layout(memory_chunk); 434 detect_memory_layout(memory_chunk);
416 S390_lowcore.machine_flags = machine_flags;
417#ifdef CONFIG_DYNAMIC_FTRACE 435#ifdef CONFIG_DYNAMIC_FTRACE
418 S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; 436 S390_lowcore.ftrace_func = (unsigned long)ftrace_caller;
419#endif 437#endif
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 5d40fce878a5..f43d2ee54464 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -278,7 +278,8 @@ sysc_return:
278 bnz BASED(sysc_work) # there is work to do (signals etc.) 278 bnz BASED(sysc_work) # there is work to do (signals etc.)
279sysc_restore: 279sysc_restore:
280#ifdef CONFIG_TRACE_IRQFLAGS 280#ifdef CONFIG_TRACE_IRQFLAGS
281 la %r1,BASED(sysc_restore_trace_psw) 281 la %r1,BASED(sysc_restore_trace_psw_addr)
282 l %r1,0(%r1)
282 lpsw 0(%r1) 283 lpsw 0(%r1)
283sysc_restore_trace: 284sysc_restore_trace:
284 TRACE_IRQS_CHECK 285 TRACE_IRQS_CHECK
@@ -289,10 +290,15 @@ sysc_leave:
289sysc_done: 290sysc_done:
290 291
291#ifdef CONFIG_TRACE_IRQFLAGS 292#ifdef CONFIG_TRACE_IRQFLAGS
293sysc_restore_trace_psw_addr:
294 .long sysc_restore_trace_psw
295
296 .section .data,"aw",@progbits
292 .align 8 297 .align 8
293 .globl sysc_restore_trace_psw 298 .globl sysc_restore_trace_psw
294sysc_restore_trace_psw: 299sysc_restore_trace_psw:
295 .long 0, sysc_restore_trace + 0x80000000 300 .long 0, sysc_restore_trace + 0x80000000
301 .previous
296#endif 302#endif
297 303
298# 304#
@@ -606,7 +612,8 @@ io_return:
606 bnz BASED(io_work) # there is work to do (signals etc.) 612 bnz BASED(io_work) # there is work to do (signals etc.)
607io_restore: 613io_restore:
608#ifdef CONFIG_TRACE_IRQFLAGS 614#ifdef CONFIG_TRACE_IRQFLAGS
609 la %r1,BASED(io_restore_trace_psw) 615 la %r1,BASED(io_restore_trace_psw_addr)
616 l %r1,0(%r1)
610 lpsw 0(%r1) 617 lpsw 0(%r1)
611io_restore_trace: 618io_restore_trace:
612 TRACE_IRQS_CHECK 619 TRACE_IRQS_CHECK
@@ -617,10 +624,15 @@ io_leave:
617io_done: 624io_done:
618 625
619#ifdef CONFIG_TRACE_IRQFLAGS 626#ifdef CONFIG_TRACE_IRQFLAGS
627io_restore_trace_psw_addr:
628 .long io_restore_trace_psw
629
630 .section .data,"aw",@progbits
620 .align 8 631 .align 8
621 .globl io_restore_trace_psw 632 .globl io_restore_trace_psw
622io_restore_trace_psw: 633io_restore_trace_psw:
623 .long 0, io_restore_trace + 0x80000000 634 .long 0, io_restore_trace + 0x80000000
635 .previous
624#endif 636#endif
625 637
626# 638#
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 3ceb53c9c493..a6f7b20df616 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -284,10 +284,12 @@ sysc_leave:
284sysc_done: 284sysc_done:
285 285
286#ifdef CONFIG_TRACE_IRQFLAGS 286#ifdef CONFIG_TRACE_IRQFLAGS
287 .section .data,"aw",@progbits
287 .align 8 288 .align 8
288 .globl sysc_restore_trace_psw 289 .globl sysc_restore_trace_psw
289sysc_restore_trace_psw: 290sysc_restore_trace_psw:
290 .quad 0, sysc_restore_trace 291 .quad 0, sysc_restore_trace
292 .previous
291#endif 293#endif
292 294
293# 295#
@@ -595,10 +597,12 @@ io_leave:
595io_done: 597io_done:
596 598
597#ifdef CONFIG_TRACE_IRQFLAGS 599#ifdef CONFIG_TRACE_IRQFLAGS
600 .section .data,"aw",@progbits
598 .align 8 601 .align 8
599 .globl io_restore_trace_psw 602 .globl io_restore_trace_psw
600io_restore_trace_psw: 603io_restore_trace_psw:
601 .quad 0, io_restore_trace 604 .quad 0, io_restore_trace
605 .previous
602#endif 606#endif
603 607
604# 608#
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index ec6882348520..c52b4f7742fa 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -27,6 +27,7 @@
27#include <asm/asm-offsets.h> 27#include <asm/asm-offsets.h>
28#include <asm/thread_info.h> 28#include <asm/thread_info.h>
29#include <asm/page.h> 29#include <asm/page.h>
30#include <asm/cpu.h>
30 31
31#ifdef CONFIG_64BIT 32#ifdef CONFIG_64BIT
32#define ARCH_OFFSET 4 33#define ARCH_OFFSET 4
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 2ced846065b7..602b508cd4c4 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -24,6 +24,7 @@ startup_continue:
24# Setup stack 24# Setup stack
25# 25#
26 l %r15,.Linittu-.LPG1(%r13) 26 l %r15,.Linittu-.LPG1(%r13)
27 st %r15,__LC_THREAD_INFO # cache thread info in lowcore
27 mvc __LC_CURRENT(4),__TI_task(%r15) 28 mvc __LC_CURRENT(4),__TI_task(%r15)
28 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE 29 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
29 st %r15,__LC_KERNEL_STACK # set end of kernel stack 30 st %r15,__LC_KERNEL_STACK # set end of kernel stack
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 65667b2e65ce..6a250808092b 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -62,9 +62,9 @@ startup_continue:
62 clr %r11,%r12 62 clr %r11,%r12
63 je 5f # no more space in prefix array 63 je 5f # no more space in prefix array
644: 644:
65 ahi %r8,1 # next cpu (r8 += 1) 65 ahi %r8,1 # next cpu (r8 += 1)
66 cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ? 66 chi %r8,MAX_CPU_ADDRESS # is last possible cpu ?
67 jl 1b # jump if not last cpu 67 jle 1b # jump if not last cpu
685: 685:
69 lhi %r1,2 # mode 2 = esame (dump) 69 lhi %r1,2 # mode 2 = esame (dump)
70 j 6f 70 j 6f
@@ -92,6 +92,7 @@ startup_continue:
92# Setup stack 92# Setup stack
93# 93#
94 larl %r15,init_thread_union 94 larl %r15,init_thread_union
95 stg %r15,__LC_THREAD_INFO # cache thread info in lowcore
95 lg %r14,__TI_task(%r15) # cache current in lowcore 96 lg %r14,__TI_task(%r15) # cache current in lowcore
96 stg %r14,__LC_CURRENT 97 stg %r14,__LC_CURRENT
97 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE 98 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
@@ -129,8 +130,6 @@ startup_continue:
129#ifdef CONFIG_ZFCPDUMP 130#ifdef CONFIG_ZFCPDUMP
130.Lcurrent_cpu: 131.Lcurrent_cpu:
131 .long 0x0 132 .long 0x0
132.Llast_cpu:
133 .long 0x0000ffff
134.Lpref_arr_ptr: 133.Lpref_arr_ptr:
135 .long zfcpdump_prefix_array 134 .long zfcpdump_prefix_array
136#endif /* CONFIG_ZFCPDUMP */ 135#endif /* CONFIG_ZFCPDUMP */
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 371a2d88f4ac..ee57a42e6e93 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -272,17 +272,18 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
272static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); 272static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
273 273
274/* VM IPL PARM routines */ 274/* VM IPL PARM routines */
275static void reipl_get_ascii_vmparm(char *dest, 275size_t reipl_get_ascii_vmparm(char *dest, size_t size,
276 const struct ipl_parameter_block *ipb) 276 const struct ipl_parameter_block *ipb)
277{ 277{
278 int i; 278 int i;
279 int len = 0; 279 size_t len;
280 char has_lowercase = 0; 280 char has_lowercase = 0;
281 281
282 len = 0;
282 if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && 283 if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) &&
283 (ipb->ipl_info.ccw.vm_parm_len > 0)) { 284 (ipb->ipl_info.ccw.vm_parm_len > 0)) {
284 285
285 len = ipb->ipl_info.ccw.vm_parm_len; 286 len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len);
286 memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); 287 memcpy(dest, ipb->ipl_info.ccw.vm_parm, len);
287 /* If at least one character is lowercase, we assume mixed 288 /* If at least one character is lowercase, we assume mixed
288 * case; otherwise we convert everything to lowercase. 289 * case; otherwise we convert everything to lowercase.
@@ -299,14 +300,20 @@ static void reipl_get_ascii_vmparm(char *dest,
299 EBCASC(dest, len); 300 EBCASC(dest, len);
300 } 301 }
301 dest[len] = 0; 302 dest[len] = 0;
303
304 return len;
302} 305}
303 306
304void get_ipl_vmparm(char *dest) 307size_t append_ipl_vmparm(char *dest, size_t size)
305{ 308{
309 size_t rc;
310
311 rc = 0;
306 if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) 312 if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW))
307 reipl_get_ascii_vmparm(dest, &ipl_block); 313 rc = reipl_get_ascii_vmparm(dest, size, &ipl_block);
308 else 314 else
309 dest[0] = 0; 315 dest[0] = 0;
316 return rc;
310} 317}
311 318
312static ssize_t ipl_vm_parm_show(struct kobject *kobj, 319static ssize_t ipl_vm_parm_show(struct kobject *kobj,
@@ -314,10 +321,65 @@ static ssize_t ipl_vm_parm_show(struct kobject *kobj,
314{ 321{
315 char parm[DIAG308_VMPARM_SIZE + 1] = {}; 322 char parm[DIAG308_VMPARM_SIZE + 1] = {};
316 323
317 get_ipl_vmparm(parm); 324 append_ipl_vmparm(parm, sizeof(parm));
318 return sprintf(page, "%s\n", parm); 325 return sprintf(page, "%s\n", parm);
319} 326}
320 327
328static size_t scpdata_length(const char* buf, size_t count)
329{
330 while (count) {
331 if (buf[count - 1] != '\0' && buf[count - 1] != ' ')
332 break;
333 count--;
334 }
335 return count;
336}
337
338size_t reipl_append_ascii_scpdata(char *dest, size_t size,
339 const struct ipl_parameter_block *ipb)
340{
341 size_t count;
342 size_t i;
343 int has_lowercase;
344
345 count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data,
346 ipb->ipl_info.fcp.scp_data_len));
347 if (!count)
348 goto out;
349
350 has_lowercase = 0;
351 for (i = 0; i < count; i++) {
352 if (!isascii(ipb->ipl_info.fcp.scp_data[i])) {
353 count = 0;
354 goto out;
355 }
356 if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i]))
357 has_lowercase = 1;
358 }
359
360 if (has_lowercase)
361 memcpy(dest, ipb->ipl_info.fcp.scp_data, count);
362 else
363 for (i = 0; i < count; i++)
364 dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]);
365out:
366 dest[count] = '\0';
367 return count;
368}
369
370size_t append_ipl_scpdata(char *dest, size_t len)
371{
372 size_t rc;
373
374 rc = 0;
375 if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP)
376 rc = reipl_append_ascii_scpdata(dest, len, &ipl_block);
377 else
378 dest[0] = 0;
379 return rc;
380}
381
382
321static struct kobj_attribute sys_ipl_vm_parm_attr = 383static struct kobj_attribute sys_ipl_vm_parm_attr =
322 __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); 384 __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL);
323 385
@@ -553,7 +615,7 @@ static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb,
553{ 615{
554 char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; 616 char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
555 617
556 reipl_get_ascii_vmparm(vmparm, ipb); 618 reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
557 return sprintf(page, "%s\n", vmparm); 619 return sprintf(page, "%s\n", vmparm);
558} 620}
559 621
@@ -626,6 +688,59 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
626 688
627/* FCP reipl device attributes */ 689/* FCP reipl device attributes */
628 690
691static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj,
692 struct bin_attribute *attr,
693 char *buf, loff_t off, size_t count)
694{
695 size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len;
696 void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data;
697
698 return memory_read_from_buffer(buf, count, &off, scp_data, size);
699}
700
701static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj,
702 struct bin_attribute *attr,
703 char *buf, loff_t off, size_t count)
704{
705 size_t padding;
706 size_t scpdata_len;
707
708 if (off < 0)
709 return -EINVAL;
710
711 if (off >= DIAG308_SCPDATA_SIZE)
712 return -ENOSPC;
713
714 if (count > DIAG308_SCPDATA_SIZE - off)
715 count = DIAG308_SCPDATA_SIZE - off;
716
717 memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count);
718 scpdata_len = off + count;
719
720 if (scpdata_len % 8) {
721 padding = 8 - (scpdata_len % 8);
722 memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len,
723 0, padding);
724 scpdata_len += padding;
725 }
726
727 reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len;
728 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len;
729 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len;
730
731 return count;
732}
733
734static struct bin_attribute sys_reipl_fcp_scp_data_attr = {
735 .attr = {
736 .name = "scp_data",
737 .mode = S_IRUGO | S_IWUSR,
738 },
739 .size = PAGE_SIZE,
740 .read = reipl_fcp_scpdata_read,
741 .write = reipl_fcp_scpdata_write,
742};
743
629DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", 744DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n",
630 reipl_block_fcp->ipl_info.fcp.wwpn); 745 reipl_block_fcp->ipl_info.fcp.wwpn);
631DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", 746DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n",
@@ -647,7 +762,6 @@ static struct attribute *reipl_fcp_attrs[] = {
647}; 762};
648 763
649static struct attribute_group reipl_fcp_attr_group = { 764static struct attribute_group reipl_fcp_attr_group = {
650 .name = IPL_FCP_STR,
651 .attrs = reipl_fcp_attrs, 765 .attrs = reipl_fcp_attrs,
652}; 766};
653 767
@@ -895,6 +1009,7 @@ static struct kobj_attribute reipl_type_attr =
895 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); 1009 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
896 1010
897static struct kset *reipl_kset; 1011static struct kset *reipl_kset;
1012static struct kset *reipl_fcp_kset;
898 1013
899static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, 1014static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
900 const enum ipl_method m) 1015 const enum ipl_method m)
@@ -906,7 +1021,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
906 1021
907 reipl_get_ascii_loadparm(loadparm, ipb); 1022 reipl_get_ascii_loadparm(loadparm, ipb);
908 reipl_get_ascii_nss_name(nss_name, ipb); 1023 reipl_get_ascii_nss_name(nss_name, ipb);
909 reipl_get_ascii_vmparm(vmparm, ipb); 1024 reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
910 1025
911 switch (m) { 1026 switch (m) {
912 case REIPL_METHOD_CCW_VM: 1027 case REIPL_METHOD_CCW_VM:
@@ -1076,23 +1191,44 @@ static int __init reipl_fcp_init(void)
1076 int rc; 1191 int rc;
1077 1192
1078 if (!diag308_set_works) { 1193 if (!diag308_set_works) {
1079 if (ipl_info.type == IPL_TYPE_FCP) 1194 if (ipl_info.type == IPL_TYPE_FCP) {
1080 make_attrs_ro(reipl_fcp_attrs); 1195 make_attrs_ro(reipl_fcp_attrs);
1081 else 1196 sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO;
1197 } else
1082 return 0; 1198 return 0;
1083 } 1199 }
1084 1200
1085 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); 1201 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1086 if (!reipl_block_fcp) 1202 if (!reipl_block_fcp)
1087 return -ENOMEM; 1203 return -ENOMEM;
1088 rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group); 1204
1205 /* sysfs: create fcp kset for mixing attr group and bin attrs */
1206 reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
1207 &reipl_kset->kobj);
1208 if (!reipl_kset) {
1209 free_page((unsigned long) reipl_block_fcp);
1210 return -ENOMEM;
1211 }
1212
1213 rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1214 if (rc) {
1215 kset_unregister(reipl_fcp_kset);
1216 free_page((unsigned long) reipl_block_fcp);
1217 return rc;
1218 }
1219
1220 rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj,
1221 &sys_reipl_fcp_scp_data_attr);
1089 if (rc) { 1222 if (rc) {
1090 free_page((unsigned long)reipl_block_fcp); 1223 sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1224 kset_unregister(reipl_fcp_kset);
1225 free_page((unsigned long) reipl_block_fcp);
1091 return rc; 1226 return rc;
1092 } 1227 }
1093 if (ipl_info.type == IPL_TYPE_FCP) { 1228
1229 if (ipl_info.type == IPL_TYPE_FCP)
1094 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); 1230 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
1095 } else { 1231 else {
1096 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; 1232 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
1097 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; 1233 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1098 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; 1234 reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index 2a0a5e97ba8c..dfe015d7398c 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -11,111 +11,27 @@
11ftrace_stub: 11ftrace_stub:
12 br %r14 12 br %r14
13 13
14#ifdef CONFIG_64BIT
15
16#ifdef CONFIG_DYNAMIC_FTRACE
17
18 .globl _mcount 14 .globl _mcount
19_mcount: 15_mcount:
20 br %r14 16#ifdef CONFIG_DYNAMIC_FTRACE
21
22 .globl ftrace_caller
23ftrace_caller:
24 larl %r1,function_trace_stop
25 icm %r1,0xf,0(%r1)
26 bnzr %r14
27 stmg %r2,%r5,32(%r15)
28 stg %r14,112(%r15)
29 lgr %r1,%r15
30 aghi %r15,-160
31 stg %r1,__SF_BACKCHAIN(%r15)
32 lgr %r2,%r14
33 lg %r3,168(%r15)
34 larl %r14,ftrace_dyn_func
35 lg %r14,0(%r14)
36 basr %r14,%r14
37#ifdef CONFIG_FUNCTION_GRAPH_TRACER
38 .globl ftrace_graph_caller
39ftrace_graph_caller:
40 # This unconditional branch gets runtime patched. Change only if
41 # you know what you are doing. See ftrace_enable_graph_caller().
42 j 0f
43 lg %r2,272(%r15)
44 lg %r3,168(%r15)
45 brasl %r14,prepare_ftrace_return
46 stg %r2,168(%r15)
470:
48#endif
49 aghi %r15,160
50 lmg %r2,%r5,32(%r15)
51 lg %r14,112(%r15)
52 br %r14 17 br %r14
53 18
54 .data 19 .data
55 .globl ftrace_dyn_func 20 .globl ftrace_dyn_func
56ftrace_dyn_func: 21ftrace_dyn_func:
57 .quad ftrace_stub 22 .long ftrace_stub
58 .previous 23 .previous
59 24
60#else /* CONFIG_DYNAMIC_FTRACE */
61
62 .globl _mcount
63_mcount:
64 larl %r1,function_trace_stop
65 icm %r1,0xf,0(%r1)
66 bnzr %r14
67 stmg %r2,%r5,32(%r15)
68 stg %r14,112(%r15)
69 lgr %r1,%r15
70 aghi %r15,-160
71 stg %r1,__SF_BACKCHAIN(%r15)
72 lgr %r2,%r14
73 lg %r3,168(%r15)
74 larl %r14,ftrace_trace_function
75 lg %r14,0(%r14)
76 basr %r14,%r14
77#ifdef CONFIG_FUNCTION_GRAPH_TRACER
78 lg %r2,272(%r15)
79 lg %r3,168(%r15)
80 brasl %r14,prepare_ftrace_return
81 stg %r2,168(%r15)
82#endif
83 aghi %r15,160
84 lmg %r2,%r5,32(%r15)
85 lg %r14,112(%r15)
86 br %r14
87
88#endif /* CONFIG_DYNAMIC_FTRACE */
89
90#ifdef CONFIG_FUNCTION_GRAPH_TRACER
91
92 .globl return_to_handler
93return_to_handler:
94 stmg %r2,%r5,32(%r15)
95 lgr %r1,%r15
96 aghi %r15,-160
97 stg %r1,__SF_BACKCHAIN(%r15)
98 brasl %r14,ftrace_return_to_handler
99 aghi %r15,160
100 lgr %r14,%r2
101 lmg %r2,%r5,32(%r15)
102 br %r14
103
104#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
105
106#else /* CONFIG_64BIT */
107
108#ifdef CONFIG_DYNAMIC_FTRACE
109
110 .globl _mcount
111_mcount:
112 br %r14
113
114 .globl ftrace_caller 25 .globl ftrace_caller
115ftrace_caller: 26ftrace_caller:
27#endif
116 stm %r2,%r5,16(%r15) 28 stm %r2,%r5,16(%r15)
117 bras %r1,2f 29 bras %r1,2f
30#ifdef CONFIG_DYNAMIC_FTRACE
310: .long ftrace_dyn_func
32#else
1180: .long ftrace_trace_function 330: .long ftrace_trace_function
34#endif
1191: .long function_trace_stop 351: .long function_trace_stop
1202: l %r2,1b-0b(%r1) 362: l %r2,1b-0b(%r1)
121 icm %r2,0xf,0(%r2) 37 icm %r2,0xf,0(%r2)
@@ -131,53 +47,13 @@ ftrace_caller:
131 l %r14,0(%r14) 47 l %r14,0(%r14)
132 basr %r14,%r14 48 basr %r14,%r14
133#ifdef CONFIG_FUNCTION_GRAPH_TRACER 49#ifdef CONFIG_FUNCTION_GRAPH_TRACER
50#ifdef CONFIG_DYNAMIC_FTRACE
134 .globl ftrace_graph_caller 51 .globl ftrace_graph_caller
135ftrace_graph_caller: 52ftrace_graph_caller:
136 # This unconditional branch gets runtime patched. Change only if 53 # This unconditional branch gets runtime patched. Change only if
137 # you know what you are doing. See ftrace_enable_graph_caller(). 54 # you know what you are doing. See ftrace_enable_graph_caller().
138 j 1f 55 j 1f
139 bras %r1,0f
140 .long prepare_ftrace_return
1410: l %r2,152(%r15)
142 l %r4,0(%r1)
143 l %r3,100(%r15)
144 basr %r14,%r4
145 st %r2,100(%r15)
1461:
147#endif 56#endif
148 ahi %r15,96
149 l %r14,56(%r15)
1503: lm %r2,%r5,16(%r15)
151 br %r14
152
153 .data
154 .globl ftrace_dyn_func
155ftrace_dyn_func:
156 .long ftrace_stub
157 .previous
158
159#else /* CONFIG_DYNAMIC_FTRACE */
160
161 .globl _mcount
162_mcount:
163 stm %r2,%r5,16(%r15)
164 bras %r1,2f
1650: .long ftrace_trace_function
1661: .long function_trace_stop
1672: l %r2,1b-0b(%r1)
168 icm %r2,0xf,0(%r2)
169 jnz 3f
170 st %r14,56(%r15)
171 lr %r0,%r15
172 ahi %r15,-96
173 l %r3,100(%r15)
174 la %r2,0(%r14)
175 st %r0,__SF_BACKCHAIN(%r15)
176 la %r3,0(%r3)
177 l %r14,0b-0b(%r1)
178 l %r14,0(%r14)
179 basr %r14,%r14
180#ifdef CONFIG_FUNCTION_GRAPH_TRACER
181 bras %r1,0f 57 bras %r1,0f
182 .long prepare_ftrace_return 58 .long prepare_ftrace_return
1830: l %r2,152(%r15) 590: l %r2,152(%r15)
@@ -185,14 +61,13 @@ _mcount:
185 l %r3,100(%r15) 61 l %r3,100(%r15)
186 basr %r14,%r4 62 basr %r14,%r4
187 st %r2,100(%r15) 63 st %r2,100(%r15)
641:
188#endif 65#endif
189 ahi %r15,96 66 ahi %r15,96
190 l %r14,56(%r15) 67 l %r14,56(%r15)
1913: lm %r2,%r5,16(%r15) 683: lm %r2,%r5,16(%r15)
192 br %r14 69 br %r14
193 70
194#endif /* CONFIG_DYNAMIC_FTRACE */
195
196#ifdef CONFIG_FUNCTION_GRAPH_TRACER 71#ifdef CONFIG_FUNCTION_GRAPH_TRACER
197 72
198 .globl return_to_handler 73 .globl return_to_handler
@@ -211,6 +86,4 @@ return_to_handler:
211 lm %r2,%r5,16(%r15) 86 lm %r2,%r5,16(%r15)
212 br %r14 87 br %r14
213 88
214#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 89#endif
215
216#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S
new file mode 100644
index 000000000000..c37211c6092b
--- /dev/null
+++ b/arch/s390/kernel/mcount64.S
@@ -0,0 +1,78 @@
1/*
2 * Copyright IBM Corp. 2008,2009
3 *
4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
5 *
6 */
7
8#include <asm/asm-offsets.h>
9
10 .globl ftrace_stub
11ftrace_stub:
12 br %r14
13
14 .globl _mcount
15_mcount:
16#ifdef CONFIG_DYNAMIC_FTRACE
17 br %r14
18
19 .data
20 .globl ftrace_dyn_func
21ftrace_dyn_func:
22 .quad ftrace_stub
23 .previous
24
25 .globl ftrace_caller
26ftrace_caller:
27#endif
28 larl %r1,function_trace_stop
29 icm %r1,0xf,0(%r1)
30 bnzr %r14
31 stmg %r2,%r5,32(%r15)
32 stg %r14,112(%r15)
33 lgr %r1,%r15
34 aghi %r15,-160
35 stg %r1,__SF_BACKCHAIN(%r15)
36 lgr %r2,%r14
37 lg %r3,168(%r15)
38#ifdef CONFIG_DYNAMIC_FTRACE
39 larl %r14,ftrace_dyn_func
40#else
41 larl %r14,ftrace_trace_function
42#endif
43 lg %r14,0(%r14)
44 basr %r14,%r14
45#ifdef CONFIG_FUNCTION_GRAPH_TRACER
46#ifdef CONFIG_DYNAMIC_FTRACE
47 .globl ftrace_graph_caller
48ftrace_graph_caller:
49 # This unconditional branch gets runtime patched. Change only if
50 # you know what you are doing. See ftrace_enable_graph_caller().
51 j 0f
52#endif
53 lg %r2,272(%r15)
54 lg %r3,168(%r15)
55 brasl %r14,prepare_ftrace_return
56 stg %r2,168(%r15)
570:
58#endif
59 aghi %r15,160
60 lmg %r2,%r5,32(%r15)
61 lg %r14,112(%r15)
62 br %r14
63
64#ifdef CONFIG_FUNCTION_GRAPH_TRACER
65
66 .globl return_to_handler
67return_to_handler:
68 stmg %r2,%r5,32(%r15)
69 lgr %r1,%r15
70 aghi %r15,-160
71 stg %r1,__SF_BACKCHAIN(%r15)
72 brasl %r14,ftrace_return_to_handler
73 aghi %r15,160
74 lgr %r14,%r2
75 lmg %r2,%r5,32(%r15)
76 br %r14
77
78#endif
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index cbb897bc50bd..9ed13a1ed376 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -156,15 +156,11 @@ __setup("condev=", condev_setup);
156 156
157static void __init set_preferred_console(void) 157static void __init set_preferred_console(void)
158{ 158{
159 if (MACHINE_IS_KVM) { 159 if (MACHINE_IS_KVM)
160 add_preferred_console("hvc", 0, NULL); 160 add_preferred_console("hvc", 0, NULL);
161 s390_virtio_console_init(); 161 else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
162 return;
163 }
164
165 if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
166 add_preferred_console("ttyS", 0, NULL); 162 add_preferred_console("ttyS", 0, NULL);
167 if (CONSOLE_IS_3270) 163 else if (CONSOLE_IS_3270)
168 add_preferred_console("tty3270", 0, NULL); 164 add_preferred_console("tty3270", 0, NULL);
169} 165}
170 166
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 062bd64e65fa..6b4fef877f9d 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -536,4 +536,6 @@ void do_notify_resume(struct pt_regs *regs)
536{ 536{
537 clear_thread_flag(TIF_NOTIFY_RESUME); 537 clear_thread_flag(TIF_NOTIFY_RESUME);
538 tracehook_notify_resume(regs); 538 tracehook_notify_resume(regs);
539 if (current->replacement_session_keyring)
540 key_replace_session_keyring();
539} 541}
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index be2cae083406..56c16876b919 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -49,6 +49,7 @@
49#include <asm/sclp.h> 49#include <asm/sclp.h>
50#include <asm/cputime.h> 50#include <asm/cputime.h>
51#include <asm/vdso.h> 51#include <asm/vdso.h>
52#include <asm/cpu.h>
52#include "entry.h" 53#include "entry.h"
53 54
54static struct task_struct *current_set[NR_CPUS]; 55static struct task_struct *current_set[NR_CPUS];
@@ -70,6 +71,23 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
70 71
71static void smp_ext_bitcall(int, ec_bit_sig); 72static void smp_ext_bitcall(int, ec_bit_sig);
72 73
74static int cpu_stopped(int cpu)
75{
76 __u32 status;
77
78 switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
79 case sigp_order_code_accepted:
80 case sigp_status_stored:
81 /* Check for stopped and check stop state */
82 if (status & 0x50)
83 return 1;
84 break;
85 default:
86 break;
87 }
88 return 0;
89}
90
73void smp_send_stop(void) 91void smp_send_stop(void)
74{ 92{
75 int cpu, rc; 93 int cpu, rc;
@@ -86,7 +104,7 @@ void smp_send_stop(void)
86 rc = signal_processor(cpu, sigp_stop); 104 rc = signal_processor(cpu, sigp_stop);
87 } while (rc == sigp_busy); 105 } while (rc == sigp_busy);
88 106
89 while (!smp_cpu_not_running(cpu)) 107 while (!cpu_stopped(cpu))
90 cpu_relax(); 108 cpu_relax();
91 } 109 }
92} 110}
@@ -269,19 +287,6 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
269 287
270#endif /* CONFIG_ZFCPDUMP */ 288#endif /* CONFIG_ZFCPDUMP */
271 289
272static int cpu_stopped(int cpu)
273{
274 __u32 status;
275
276 /* Check for stopped state */
277 if (signal_processor_ps(&status, 0, cpu, sigp_sense) ==
278 sigp_status_stored) {
279 if (status & 0x40)
280 return 1;
281 }
282 return 0;
283}
284
285static int cpu_known(int cpu_id) 290static int cpu_known(int cpu_id)
286{ 291{
287 int cpu; 292 int cpu;
@@ -300,7 +305,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
300 logical_cpu = cpumask_first(&avail); 305 logical_cpu = cpumask_first(&avail);
301 if (logical_cpu >= nr_cpu_ids) 306 if (logical_cpu >= nr_cpu_ids)
302 return 0; 307 return 0;
303 for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { 308 for (cpu_id = 0; cpu_id <= MAX_CPU_ADDRESS; cpu_id++) {
304 if (cpu_known(cpu_id)) 309 if (cpu_known(cpu_id))
305 continue; 310 continue;
306 __cpu_logical_map[logical_cpu] = cpu_id; 311 __cpu_logical_map[logical_cpu] = cpu_id;
@@ -379,7 +384,7 @@ static void __init smp_detect_cpus(void)
379 /* Use sigp detection algorithm if sclp doesn't work. */ 384 /* Use sigp detection algorithm if sclp doesn't work. */
380 if (sclp_get_cpu_info(info)) { 385 if (sclp_get_cpu_info(info)) {
381 smp_use_sigp_detection = 1; 386 smp_use_sigp_detection = 1;
382 for (cpu = 0; cpu <= 65535; cpu++) { 387 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
383 if (cpu == boot_cpu_addr) 388 if (cpu == boot_cpu_addr)
384 continue; 389 continue;
385 __cpu_logical_map[CPU_INIT_NO] = cpu; 390 __cpu_logical_map[CPU_INIT_NO] = cpu;
@@ -635,7 +640,7 @@ int __cpu_disable(void)
635void __cpu_die(unsigned int cpu) 640void __cpu_die(unsigned int cpu)
636{ 641{
637 /* Wait until target cpu is down */ 642 /* Wait until target cpu is down */
638 while (!smp_cpu_not_running(cpu)) 643 while (!cpu_stopped(cpu))
639 cpu_relax(); 644 cpu_relax();
640 smp_free_lowcore(cpu); 645 smp_free_lowcore(cpu);
641 pr_info("Processor %d stopped\n", cpu); 646 pr_info("Processor %d stopped\n", cpu);
diff --git a/arch/s390/power/swsusp.c b/arch/s390/kernel/suspend.c
index bd1f5c6b0b8c..086bee970cae 100644
--- a/arch/s390/power/swsusp.c
+++ b/arch/s390/kernel/suspend.c
@@ -1,13 +1,44 @@
1/* 1/*
2 * Support for suspend and resume on s390 2 * Suspend support specific for s390.
3 * 3 *
4 * Copyright IBM Corp. 2009 4 * Copyright IBM Corp. 2009
5 * 5 *
6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> 6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com>
7 *
8 */ 7 */
9 8
9#include <linux/suspend.h>
10#include <linux/reboot.h>
11#include <linux/pfn.h>
12#include <linux/mm.h>
13#include <asm/sections.h>
10#include <asm/system.h> 14#include <asm/system.h>
15#include <asm/ipl.h>
16
17/*
18 * References to section boundaries
19 */
20extern const void __nosave_begin, __nosave_end;
21
22/*
23 * check if given pfn is in the 'nosave' or in the read only NSS section
24 */
25int pfn_is_nosave(unsigned long pfn)
26{
27 unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
28 unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end))
29 >> PAGE_SHIFT;
30 unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
31 unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
32
33 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
34 return 1;
35 if (pfn >= stext_pfn && pfn <= eshared_pfn) {
36 if (ipl_info.type == IPL_TYPE_NSS)
37 return 1;
38 } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0))
39 return 1;
40 return 0;
41}
11 42
12void save_processor_state(void) 43void save_processor_state(void)
13{ 44{
diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index b26df5c5933e..7cd6b096f0d1 100644
--- a/arch/s390/power/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -21,7 +21,7 @@
21 * This function runs with disabled interrupts. 21 * This function runs with disabled interrupts.
22 */ 22 */
23 .section .text 23 .section .text
24 .align 2 24 .align 4
25 .globl swsusp_arch_suspend 25 .globl swsusp_arch_suspend
26swsusp_arch_suspend: 26swsusp_arch_suspend:
27 stmg %r6,%r15,__SF_GPRS(%r15) 27 stmg %r6,%r15,__SF_GPRS(%r15)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index d4c8e9c47c81..e3dc28b8075d 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -60,6 +60,7 @@
60#define TICK_SIZE tick 60#define TICK_SIZE tick
61 61
62u64 sched_clock_base_cc = -1; /* Force to data section. */ 62u64 sched_clock_base_cc = -1; /* Force to data section. */
63EXPORT_SYMBOL_GPL(sched_clock_base_cc);
63 64
64static DEFINE_PER_CPU(struct clock_event_device, comparators); 65static DEFINE_PER_CPU(struct clock_event_device, comparators);
65 66
@@ -68,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
68 */ 69 */
69unsigned long long notrace sched_clock(void) 70unsigned long long notrace sched_clock(void)
70{ 71{
71 return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9; 72 return (get_clock_monotonic() * 125) >> 9;
72} 73}
73 74
74/* 75/*
@@ -90,6 +91,7 @@ void tod_to_timeval(__u64 todval, struct timespec *xtime)
90 todval -= (sec * 1000000) << 12; 91 todval -= (sec * 1000000) << 12;
91 xtime->tv_nsec = ((todval * 1000) >> 12); 92 xtime->tv_nsec = ((todval * 1000) >> 12);
92} 93}
94EXPORT_SYMBOL(tod_to_timeval);
93 95
94void clock_comparator_work(void) 96void clock_comparator_work(void)
95{ 97{
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index a53db23ee092..7315f9e67e1d 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -52,55 +52,18 @@ SECTIONS
52 . = ALIGN(PAGE_SIZE); 52 . = ALIGN(PAGE_SIZE);
53 _eshared = .; /* End of shareable data */ 53 _eshared = .; /* End of shareable data */
54 54
55 . = ALIGN(16); /* Exception table */ 55 EXCEPTION_TABLE(16) :data
56 __ex_table : {
57 __start___ex_table = .;
58 *(__ex_table)
59 __stop___ex_table = .;
60 } :data
61
62 .data : { /* Data */
63 DATA_DATA
64 CONSTRUCTORS
65 }
66
67 . = ALIGN(PAGE_SIZE);
68 .data_nosave : {
69 __nosave_begin = .;
70 *(.data.nosave)
71 }
72 . = ALIGN(PAGE_SIZE);
73 __nosave_end = .;
74
75 . = ALIGN(PAGE_SIZE);
76 .data.page_aligned : {
77 *(.data.idt)
78 }
79 56
80 . = ALIGN(0x100); 57 RW_DATA_SECTION(0x100, PAGE_SIZE, THREAD_SIZE)
81 .data.cacheline_aligned : {
82 *(.data.cacheline_aligned)
83 }
84 58
85 . = ALIGN(0x100);
86 .data.read_mostly : {
87 *(.data.read_mostly)
88 }
89 _edata = .; /* End of data section */ 59 _edata = .; /* End of data section */
90 60
91 . = ALIGN(THREAD_SIZE); /* init_task */
92 .data.init_task : {
93 *(.data.init_task)
94 }
95
96 /* will be freed after init */ 61 /* will be freed after init */
97 . = ALIGN(PAGE_SIZE); /* Init code and data */ 62 . = ALIGN(PAGE_SIZE); /* Init code and data */
98 __init_begin = .; 63 __init_begin = .;
99 .init.text : { 64
100 _sinittext = .; 65 INIT_TEXT_SECTION(PAGE_SIZE)
101 INIT_TEXT 66
102 _einittext = .;
103 }
104 /* 67 /*
105 * .exit.text is discarded at runtime, not link time, 68 * .exit.text is discarded at runtime, not link time,
106 * to deal with references from __bug_table 69 * to deal with references from __bug_table
@@ -111,49 +74,13 @@ SECTIONS
111 74
112 /* early.c uses stsi, which requires page aligned data. */ 75 /* early.c uses stsi, which requires page aligned data. */
113 . = ALIGN(PAGE_SIZE); 76 . = ALIGN(PAGE_SIZE);
114 .init.data : { 77 INIT_DATA_SECTION(0x100)
115 INIT_DATA
116 }
117 . = ALIGN(0x100);
118 .init.setup : {
119 __setup_start = .;
120 *(.init.setup)
121 __setup_end = .;
122 }
123 .initcall.init : {
124 __initcall_start = .;
125 INITCALLS
126 __initcall_end = .;
127 }
128
129 .con_initcall.init : {
130 __con_initcall_start = .;
131 *(.con_initcall.init)
132 __con_initcall_end = .;
133 }
134 SECURITY_INIT
135
136#ifdef CONFIG_BLK_DEV_INITRD
137 . = ALIGN(0x100);
138 .init.ramfs : {
139 __initramfs_start = .;
140 *(.init.ramfs)
141 . = ALIGN(2);
142 __initramfs_end = .;
143 }
144#endif
145 78
146 PERCPU(PAGE_SIZE) 79 PERCPU(PAGE_SIZE)
147 . = ALIGN(PAGE_SIZE); 80 . = ALIGN(PAGE_SIZE);
148 __init_end = .; /* freed after init ends here */ 81 __init_end = .; /* freed after init ends here */
149 82
150 /* BSS */ 83 BSS_SECTION(0, 2, 0)
151 .bss : {
152 __bss_start = .;
153 *(.bss)
154 . = ALIGN(2);
155 __bss_stop = .;
156 }
157 84
158 _end = . ; 85 _end = . ;
159 86
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 3e260b7e37b2..bf164fc21864 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -1,11 +1,7 @@
1# 1#
2# KVM configuration 2# KVM configuration
3# 3#
4config HAVE_KVM 4source "virt/kvm/Kconfig"
5 bool
6
7config HAVE_KVM_IRQCHIP
8 bool
9 5
10menuconfig VIRTUALIZATION 6menuconfig VIRTUALIZATION
11 bool "Virtualization" 7 bool "Virtualization"
@@ -38,9 +34,6 @@ config KVM
38 34
39 If unsure, say N. 35 If unsure, say N.
40 36
41config KVM_TRACE
42 bool
43
44# OK, it's a little counter-intuitive to do this, but it puts it neatly under 37# OK, it's a little counter-intuitive to do this, but it puts it neatly under
45# the virtualization menu. 38# the virtualization menu.
46source drivers/virtio/Kconfig 39source drivers/virtio/Kconfig
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index ed60f3a74a85..03c716a0f01f 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * gaccess.h - access guest memory 2 * gaccess.h - access guest memory
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2009
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -16,13 +16,14 @@
16#include <linux/compiler.h> 16#include <linux/compiler.h>
17#include <linux/kvm_host.h> 17#include <linux/kvm_host.h>
18#include <asm/uaccess.h> 18#include <asm/uaccess.h>
19#include "kvm-s390.h"
19 20
20static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, 21static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu,
21 unsigned long guestaddr) 22 unsigned long guestaddr)
22{ 23{
23 unsigned long prefix = vcpu->arch.sie_block->prefix; 24 unsigned long prefix = vcpu->arch.sie_block->prefix;
24 unsigned long origin = vcpu->kvm->arch.guest_origin; 25 unsigned long origin = vcpu->arch.sie_block->gmsor;
25 unsigned long memsize = vcpu->kvm->arch.guest_memsize; 26 unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
26 27
27 if (guestaddr < 2 * PAGE_SIZE) 28 if (guestaddr < 2 * PAGE_SIZE)
28 guestaddr += prefix; 29 guestaddr += prefix;
@@ -158,8 +159,8 @@ static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest,
158 const void *from, unsigned long n) 159 const void *from, unsigned long n)
159{ 160{
160 unsigned long prefix = vcpu->arch.sie_block->prefix; 161 unsigned long prefix = vcpu->arch.sie_block->prefix;
161 unsigned long origin = vcpu->kvm->arch.guest_origin; 162 unsigned long origin = vcpu->arch.sie_block->gmsor;
162 unsigned long memsize = vcpu->kvm->arch.guest_memsize; 163 unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
163 164
164 if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE)) 165 if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE))
165 goto slowpath; 166 goto slowpath;
@@ -209,8 +210,8 @@ static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to,
209 unsigned long guestsrc, unsigned long n) 210 unsigned long guestsrc, unsigned long n)
210{ 211{
211 unsigned long prefix = vcpu->arch.sie_block->prefix; 212 unsigned long prefix = vcpu->arch.sie_block->prefix;
212 unsigned long origin = vcpu->kvm->arch.guest_origin; 213 unsigned long origin = vcpu->arch.sie_block->gmsor;
213 unsigned long memsize = vcpu->kvm->arch.guest_memsize; 214 unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
214 215
215 if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE)) 216 if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE))
216 goto slowpath; 217 goto slowpath;
@@ -244,8 +245,8 @@ static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu,
244 unsigned long guestdest, 245 unsigned long guestdest,
245 const void *from, unsigned long n) 246 const void *from, unsigned long n)
246{ 247{
247 unsigned long origin = vcpu->kvm->arch.guest_origin; 248 unsigned long origin = vcpu->arch.sie_block->gmsor;
248 unsigned long memsize = vcpu->kvm->arch.guest_memsize; 249 unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
249 250
250 if (guestdest + n > memsize) 251 if (guestdest + n > memsize)
251 return -EFAULT; 252 return -EFAULT;
@@ -262,8 +263,8 @@ static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to,
262 unsigned long guestsrc, 263 unsigned long guestsrc,
263 unsigned long n) 264 unsigned long n)
264{ 265{
265 unsigned long origin = vcpu->kvm->arch.guest_origin; 266 unsigned long origin = vcpu->arch.sie_block->gmsor;
266 unsigned long memsize = vcpu->kvm->arch.guest_memsize; 267 unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
267 268
268 if (guestsrc + n > memsize) 269 if (guestsrc + n > memsize)
269 return -EFAULT; 270 return -EFAULT;
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 98997ccba501..ba9d8a7bc1ac 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * intercept.c - in-kernel handling for sie intercepts 2 * intercept.c - in-kernel handling for sie intercepts
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2009
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -128,7 +128,7 @@ static int handle_noop(struct kvm_vcpu *vcpu)
128 128
129static int handle_stop(struct kvm_vcpu *vcpu) 129static int handle_stop(struct kvm_vcpu *vcpu)
130{ 130{
131 int rc; 131 int rc = 0;
132 132
133 vcpu->stat.exit_stop_request++; 133 vcpu->stat.exit_stop_request++;
134 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); 134 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
@@ -141,12 +141,18 @@ static int handle_stop(struct kvm_vcpu *vcpu)
141 rc = -ENOTSUPP; 141 rc = -ENOTSUPP;
142 } 142 }
143 143
144 if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) {
145 vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP;
146 rc = SIE_INTERCEPT_RERUNVCPU;
147 vcpu->run->exit_reason = KVM_EXIT_INTR;
148 }
149
144 if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { 150 if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
145 vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; 151 vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
146 VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); 152 VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
147 rc = -ENOTSUPP; 153 rc = -ENOTSUPP;
148 } else 154 }
149 rc = 0; 155
150 spin_unlock_bh(&vcpu->arch.local_int.lock); 156 spin_unlock_bh(&vcpu->arch.local_int.lock);
151 return rc; 157 return rc;
152} 158}
@@ -158,9 +164,9 @@ static int handle_validity(struct kvm_vcpu *vcpu)
158 164
159 vcpu->stat.exit_validity++; 165 vcpu->stat.exit_validity++;
160 if ((viwhy == 0x37) && (vcpu->arch.sie_block->prefix 166 if ((viwhy == 0x37) && (vcpu->arch.sie_block->prefix
161 <= vcpu->kvm->arch.guest_memsize - 2*PAGE_SIZE)){ 167 <= kvm_s390_vcpu_get_memsize(vcpu) - 2*PAGE_SIZE)) {
162 rc = fault_in_pages_writeable((char __user *) 168 rc = fault_in_pages_writeable((char __user *)
163 vcpu->kvm->arch.guest_origin + 169 vcpu->arch.sie_block->gmsor +
164 vcpu->arch.sie_block->prefix, 170 vcpu->arch.sie_block->prefix,
165 2*PAGE_SIZE); 171 2*PAGE_SIZE);
166 if (rc) 172 if (rc)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 4d613415c435..2c2f98353415 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -283,7 +283,7 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu)
283 return 1; 283 return 1;
284} 284}
285 285
286int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) 286static int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
287{ 287{
288 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 288 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
289 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; 289 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
@@ -320,12 +320,6 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
320 return rc; 320 return rc;
321} 321}
322 322
323int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
324{
325 /* do real check here */
326 return 1;
327}
328
329int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) 323int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
330{ 324{
331 return 0; 325 return 0;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 90d9d1ba258b..07ced89740d7 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * s390host.c -- hosting zSeries kernel virtual machines 2 * s390host.c -- hosting zSeries kernel virtual machines
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2009
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -10,6 +10,7 @@
10 * Author(s): Carsten Otte <cotte@de.ibm.com> 10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com> 11 * Christian Borntraeger <borntraeger@de.ibm.com>
12 * Heiko Carstens <heiko.carstens@de.ibm.com> 12 * Heiko Carstens <heiko.carstens@de.ibm.com>
13 * Christian Ehrhardt <ehrhardt@de.ibm.com>
13 */ 14 */
14 15
15#include <linux/compiler.h> 16#include <linux/compiler.h>
@@ -210,13 +211,17 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
210static void kvm_free_vcpus(struct kvm *kvm) 211static void kvm_free_vcpus(struct kvm *kvm)
211{ 212{
212 unsigned int i; 213 unsigned int i;
214 struct kvm_vcpu *vcpu;
213 215
214 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 216 kvm_for_each_vcpu(i, vcpu, kvm)
215 if (kvm->vcpus[i]) { 217 kvm_arch_vcpu_destroy(vcpu);
216 kvm_arch_vcpu_destroy(kvm->vcpus[i]); 218
217 kvm->vcpus[i] = NULL; 219 mutex_lock(&kvm->lock);
218 } 220 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
219 } 221 kvm->vcpus[i] = NULL;
222
223 atomic_set(&kvm->online_vcpus, 0);
224 mutex_unlock(&kvm->lock);
220} 225}
221 226
222void kvm_arch_sync_events(struct kvm *kvm) 227void kvm_arch_sync_events(struct kvm *kvm)
@@ -278,16 +283,10 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
278 vcpu->arch.sie_block->gbea = 1; 283 vcpu->arch.sie_block->gbea = 1;
279} 284}
280 285
281/* The current code can have up to 256 pages for virtio */
282#define VIRTIODESCSPACE (256ul * 4096ul)
283
284int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) 286int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
285{ 287{
286 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH); 288 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
287 vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize + 289 set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
288 vcpu->kvm->arch.guest_origin +
289 VIRTIODESCSPACE - 1ul;
290 vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
291 vcpu->arch.sie_block->ecb = 2; 290 vcpu->arch.sie_block->ecb = 2;
292 vcpu->arch.sie_block->eca = 0xC1002001U; 291 vcpu->arch.sie_block->eca = 0xC1002001U;
293 vcpu->arch.sie_block->fac = (int) (long) facilities; 292 vcpu->arch.sie_block->fac = (int) (long) facilities;
@@ -319,8 +318,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
319 BUG_ON(!kvm->arch.sca); 318 BUG_ON(!kvm->arch.sca);
320 if (!kvm->arch.sca->cpu[id].sda) 319 if (!kvm->arch.sca->cpu[id].sda)
321 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block; 320 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
322 else
323 BUG_ON(!kvm->vcpus[id]); /* vcpu does already exist */
324 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32); 321 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
325 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; 322 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
326 323
@@ -490,9 +487,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
490 487
491 vcpu_load(vcpu); 488 vcpu_load(vcpu);
492 489
490rerun_vcpu:
491 if (vcpu->requests)
492 if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
493 kvm_s390_vcpu_set_mem(vcpu);
494
493 /* verify, that memory has been registered */ 495 /* verify, that memory has been registered */
494 if (!vcpu->kvm->arch.guest_memsize) { 496 if (!vcpu->arch.sie_block->gmslm) {
495 vcpu_put(vcpu); 497 vcpu_put(vcpu);
498 VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu");
496 return -EINVAL; 499 return -EINVAL;
497 } 500 }
498 501
@@ -509,6 +512,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
509 vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; 512 vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
510 break; 513 break;
511 case KVM_EXIT_UNKNOWN: 514 case KVM_EXIT_UNKNOWN:
515 case KVM_EXIT_INTR:
512 case KVM_EXIT_S390_RESET: 516 case KVM_EXIT_S390_RESET:
513 break; 517 break;
514 default: 518 default:
@@ -522,8 +526,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
522 rc = kvm_handle_sie_intercept(vcpu); 526 rc = kvm_handle_sie_intercept(vcpu);
523 } while (!signal_pending(current) && !rc); 527 } while (!signal_pending(current) && !rc);
524 528
525 if (signal_pending(current) && !rc) 529 if (rc == SIE_INTERCEPT_RERUNVCPU)
530 goto rerun_vcpu;
531
532 if (signal_pending(current) && !rc) {
533 kvm_run->exit_reason = KVM_EXIT_INTR;
526 rc = -EINTR; 534 rc = -EINTR;
535 }
527 536
528 if (rc == -ENOTSUPP) { 537 if (rc == -ENOTSUPP) {
529 /* intercept cannot be handled in-kernel, prepare kvm-run */ 538 /* intercept cannot be handled in-kernel, prepare kvm-run */
@@ -676,6 +685,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
676 int user_alloc) 685 int user_alloc)
677{ 686{
678 int i; 687 int i;
688 struct kvm_vcpu *vcpu;
679 689
680 /* A few sanity checks. We can have exactly one memory slot which has 690 /* A few sanity checks. We can have exactly one memory slot which has
681 to start at guest virtual zero and which has to be located at a 691 to start at guest virtual zero and which has to be located at a
@@ -684,7 +694,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
684 vmas. It is okay to mmap() and munmap() stuff in this slot after 694 vmas. It is okay to mmap() and munmap() stuff in this slot after
685 doing this call at any time */ 695 doing this call at any time */
686 696
687 if (mem->slot || kvm->arch.guest_memsize) 697 if (mem->slot)
688 return -EINVAL; 698 return -EINVAL;
689 699
690 if (mem->guest_phys_addr) 700 if (mem->guest_phys_addr)
@@ -699,36 +709,14 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
699 if (!user_alloc) 709 if (!user_alloc)
700 return -EINVAL; 710 return -EINVAL;
701 711
702 /* lock all vcpus */ 712 /* request update of sie control block for all available vcpus */
703 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 713 kvm_for_each_vcpu(i, vcpu, kvm) {
704 if (!kvm->vcpus[i]) 714 if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
705 continue; 715 continue;
706 if (!mutex_trylock(&kvm->vcpus[i]->mutex)) 716 kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
707 goto fail_out;
708 }
709
710 kvm->arch.guest_origin = mem->userspace_addr;
711 kvm->arch.guest_memsize = mem->memory_size;
712
713 /* update sie control blocks, and unlock all vcpus */
714 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
715 if (kvm->vcpus[i]) {
716 kvm->vcpus[i]->arch.sie_block->gmsor =
717 kvm->arch.guest_origin;
718 kvm->vcpus[i]->arch.sie_block->gmslm =
719 kvm->arch.guest_memsize +
720 kvm->arch.guest_origin +
721 VIRTIODESCSPACE - 1ul;
722 mutex_unlock(&kvm->vcpus[i]->mutex);
723 }
724 } 717 }
725 718
726 return 0; 719 return 0;
727
728fail_out:
729 for (; i >= 0; i--)
730 mutex_unlock(&kvm->vcpus[i]->mutex);
731 return -EINVAL;
732} 720}
733 721
734void kvm_arch_flush_shadow(struct kvm *kvm) 722void kvm_arch_flush_shadow(struct kvm *kvm)
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 748fee872323..ec5eee7c25d8 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * kvm_s390.h - definition for kvm on s390 2 * kvm_s390.h - definition for kvm on s390
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2009
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -9,6 +9,7 @@
9 * 9 *
10 * Author(s): Carsten Otte <cotte@de.ibm.com> 10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com> 11 * Christian Borntraeger <borntraeger@de.ibm.com>
12 * Christian Ehrhardt <ehrhardt@de.ibm.com>
12 */ 13 */
13 14
14#ifndef ARCH_S390_KVM_S390_H 15#ifndef ARCH_S390_KVM_S390_H
@@ -18,8 +19,13 @@
18#include <linux/kvm.h> 19#include <linux/kvm.h>
19#include <linux/kvm_host.h> 20#include <linux/kvm_host.h>
20 21
22/* The current code can have up to 256 pages for virtio */
23#define VIRTIODESCSPACE (256ul * 4096ul)
24
21typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); 25typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
22 26
27/* negativ values are error codes, positive values for internal conditions */
28#define SIE_INTERCEPT_RERUNVCPU (1<<0)
23int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); 29int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
24 30
25#define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ 31#define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\
@@ -50,6 +56,30 @@ int kvm_s390_inject_vm(struct kvm *kvm,
50int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, 56int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
51 struct kvm_s390_interrupt *s390int); 57 struct kvm_s390_interrupt *s390int);
52int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); 58int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
59int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
60
61static inline int kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
62{
63 return vcpu->arch.sie_block->gmslm
64 - vcpu->arch.sie_block->gmsor
65 - VIRTIODESCSPACE + 1ul;
66}
67
68static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
69{
70 struct kvm_memory_slot *mem;
71
72 down_read(&vcpu->kvm->slots_lock);
73 mem = &vcpu->kvm->memslots[0];
74
75 vcpu->arch.sie_block->gmsor = mem->userspace_addr;
76 vcpu->arch.sie_block->gmslm =
77 mem->userspace_addr +
78 (mem->npages << PAGE_SHIFT) +
79 VIRTIODESCSPACE - 1ul;
80
81 up_read(&vcpu->kvm->slots_lock);
82}
53 83
54/* implemented in priv.c */ 84/* implemented in priv.c */
55int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); 85int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 0ef81d6776e9..40c8c6748cfe 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * sigp.c - handlinge interprocessor communication 2 * sigp.c - handlinge interprocessor communication
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2009
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -9,6 +9,7 @@
9 * 9 *
10 * Author(s): Carsten Otte <cotte@de.ibm.com> 10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com> 11 * Christian Borntraeger <borntraeger@de.ibm.com>
12 * Christian Ehrhardt <ehrhardt@de.ibm.com>
12 */ 13 */
13 14
14#include <linux/kvm.h> 15#include <linux/kvm.h>
@@ -107,46 +108,57 @@ unlock:
107 return rc; 108 return rc;
108} 109}
109 110
110static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int store) 111static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
111{ 112{
112 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
113 struct kvm_s390_local_interrupt *li;
114 struct kvm_s390_interrupt_info *inti; 113 struct kvm_s390_interrupt_info *inti;
115 int rc;
116
117 if (cpu_addr >= KVM_MAX_VCPUS)
118 return 3; /* not operational */
119 114
120 inti = kzalloc(sizeof(*inti), GFP_KERNEL); 115 inti = kzalloc(sizeof(*inti), GFP_KERNEL);
121 if (!inti) 116 if (!inti)
122 return -ENOMEM; 117 return -ENOMEM;
123
124 inti->type = KVM_S390_SIGP_STOP; 118 inti->type = KVM_S390_SIGP_STOP;
125 119
126 spin_lock(&fi->lock);
127 li = fi->local_int[cpu_addr];
128 if (li == NULL) {
129 rc = 3; /* not operational */
130 kfree(inti);
131 goto unlock;
132 }
133 spin_lock_bh(&li->lock); 120 spin_lock_bh(&li->lock);
134 list_add_tail(&inti->list, &li->list); 121 list_add_tail(&inti->list, &li->list);
135 atomic_set(&li->active, 1); 122 atomic_set(&li->active, 1);
136 atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); 123 atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
137 if (store) 124 li->action_bits |= action;
138 li->action_bits |= ACTION_STORE_ON_STOP;
139 li->action_bits |= ACTION_STOP_ON_STOP;
140 if (waitqueue_active(&li->wq)) 125 if (waitqueue_active(&li->wq))
141 wake_up_interruptible(&li->wq); 126 wake_up_interruptible(&li->wq);
142 spin_unlock_bh(&li->lock); 127 spin_unlock_bh(&li->lock);
143 rc = 0; /* order accepted */ 128
129 return 0; /* order accepted */
130}
131
132static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
133{
134 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
135 struct kvm_s390_local_interrupt *li;
136 int rc;
137
138 if (cpu_addr >= KVM_MAX_VCPUS)
139 return 3; /* not operational */
140
141 spin_lock(&fi->lock);
142 li = fi->local_int[cpu_addr];
143 if (li == NULL) {
144 rc = 3; /* not operational */
145 goto unlock;
146 }
147
148 rc = __inject_sigp_stop(li, action);
149
144unlock: 150unlock:
145 spin_unlock(&fi->lock); 151 spin_unlock(&fi->lock);
146 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); 152 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
147 return rc; 153 return rc;
148} 154}
149 155
156int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action)
157{
158 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
159 return __inject_sigp_stop(li, action);
160}
161
150static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) 162static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
151{ 163{
152 int rc; 164 int rc;
@@ -177,9 +189,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
177 /* make sure that the new value is valid memory */ 189 /* make sure that the new value is valid memory */
178 address = address & 0x7fffe000u; 190 address = address & 0x7fffe000u;
179 if ((copy_from_guest(vcpu, &tmp, 191 if ((copy_from_guest(vcpu, &tmp,
180 (u64) (address + vcpu->kvm->arch.guest_origin) , 1)) || 192 (u64) (address + vcpu->arch.sie_block->gmsor) , 1)) ||
181 (copy_from_guest(vcpu, &tmp, (u64) (address + 193 (copy_from_guest(vcpu, &tmp, (u64) (address +
182 vcpu->kvm->arch.guest_origin + PAGE_SIZE), 1))) { 194 vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) {
183 *reg |= SIGP_STAT_INVALID_PARAMETER; 195 *reg |= SIGP_STAT_INVALID_PARAMETER;
184 return 1; /* invalid parameter */ 196 return 1; /* invalid parameter */
185 } 197 }
@@ -262,11 +274,11 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
262 break; 274 break;
263 case SIGP_STOP: 275 case SIGP_STOP:
264 vcpu->stat.instruction_sigp_stop++; 276 vcpu->stat.instruction_sigp_stop++;
265 rc = __sigp_stop(vcpu, cpu_addr, 0); 277 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP);
266 break; 278 break;
267 case SIGP_STOP_STORE_STATUS: 279 case SIGP_STOP_STORE_STATUS:
268 vcpu->stat.instruction_sigp_stop++; 280 vcpu->stat.instruction_sigp_stop++;
269 rc = __sigp_stop(vcpu, cpu_addr, 1); 281 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP);
270 break; 282 break;
271 case SIGP_SET_ARCH: 283 case SIGP_SET_ARCH:
272 vcpu->stat.instruction_sigp_arch++; 284 vcpu->stat.instruction_sigp_arch++;
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index db05661ac895..eec054484419 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux s390-specific parts of the memory manager. 2# Makefile for the linux s390-specific parts of the memory manager.
3# 3#
4 4
5obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o 5obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \
6 page-states.o
6obj-$(CONFIG_CMM) += cmm.o 7obj-$(CONFIG_CMM) += cmm.o
7obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
8obj-$(CONFIG_PAGE_STATES) += page-states.o
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index e5e119fe03b2..1abbadd497e1 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -10,6 +10,7 @@
10 * Copyright (C) 1995 Linus Torvalds 10 * Copyright (C) 1995 Linus Torvalds
11 */ 11 */
12 12
13#include <linux/perf_counter.h>
13#include <linux/signal.h> 14#include <linux/signal.h>
14#include <linux/sched.h> 15#include <linux/sched.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
@@ -305,7 +306,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write)
305 * interrupts again and then search the VMAs 306 * interrupts again and then search the VMAs
306 */ 307 */
307 local_irq_enable(); 308 local_irq_enable();
308 309 perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
309 down_read(&mm->mmap_sem); 310 down_read(&mm->mmap_sem);
310 311
311 si_code = SEGV_MAPERR; 312 si_code = SEGV_MAPERR;
@@ -363,11 +364,15 @@ good_area:
363 } 364 }
364 BUG(); 365 BUG();
365 } 366 }
366 if (fault & VM_FAULT_MAJOR) 367 if (fault & VM_FAULT_MAJOR) {
367 tsk->maj_flt++; 368 tsk->maj_flt++;
368 else 369 perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
370 regs, address);
371 } else {
369 tsk->min_flt++; 372 tsk->min_flt++;
370 373 perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
374 regs, address);
375 }
371 up_read(&mm->mmap_sem); 376 up_read(&mm->mmap_sem);
372 /* 377 /*
373 * The instruction that caused the program check will 378 * The instruction that caused the program check will
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c
index fc0ad73ffd90..f92ec203ad92 100644
--- a/arch/s390/mm/page-states.c
+++ b/arch/s390/mm/page-states.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/s390/mm/page-states.c
3 *
4 * Copyright IBM Corp. 2008 2 * Copyright IBM Corp. 2008
5 * 3 *
6 * Guest page hinting for unused pages. 4 * Guest page hinting for unused pages.
@@ -17,11 +15,12 @@
17#define ESSA_SET_STABLE 1 15#define ESSA_SET_STABLE 1
18#define ESSA_SET_UNUSED 2 16#define ESSA_SET_UNUSED 2
19 17
20static int cmma_flag; 18static int cmma_flag = 1;
21 19
22static int __init cmma(char *str) 20static int __init cmma(char *str)
23{ 21{
24 char *parm; 22 char *parm;
23
25 parm = strstrip(str); 24 parm = strstrip(str);
26 if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { 25 if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) {
27 cmma_flag = 1; 26 cmma_flag = 1;
@@ -32,7 +31,6 @@ static int __init cmma(char *str)
32 return 1; 31 return 1;
33 return 0; 32 return 0;
34} 33}
35
36__setup("cmma=", cmma); 34__setup("cmma=", cmma);
37 35
38void __init cmma_init(void) 36void __init cmma_init(void)
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 565667207985..c70215247071 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -78,9 +78,9 @@ unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
78 } 78 }
79 page->index = page_to_phys(shadow); 79 page->index = page_to_phys(shadow);
80 } 80 }
81 spin_lock(&mm->page_table_lock); 81 spin_lock(&mm->context.list_lock);
82 list_add(&page->lru, &mm->context.crst_list); 82 list_add(&page->lru, &mm->context.crst_list);
83 spin_unlock(&mm->page_table_lock); 83 spin_unlock(&mm->context.list_lock);
84 return (unsigned long *) page_to_phys(page); 84 return (unsigned long *) page_to_phys(page);
85} 85}
86 86
@@ -89,9 +89,9 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table)
89 unsigned long *shadow = get_shadow_table(table); 89 unsigned long *shadow = get_shadow_table(table);
90 struct page *page = virt_to_page(table); 90 struct page *page = virt_to_page(table);
91 91
92 spin_lock(&mm->page_table_lock); 92 spin_lock(&mm->context.list_lock);
93 list_del(&page->lru); 93 list_del(&page->lru);
94 spin_unlock(&mm->page_table_lock); 94 spin_unlock(&mm->context.list_lock);
95 if (shadow) 95 if (shadow)
96 free_pages((unsigned long) shadow, ALLOC_ORDER); 96 free_pages((unsigned long) shadow, ALLOC_ORDER);
97 free_pages((unsigned long) table, ALLOC_ORDER); 97 free_pages((unsigned long) table, ALLOC_ORDER);
@@ -182,7 +182,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
182 unsigned long bits; 182 unsigned long bits;
183 183
184 bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; 184 bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
185 spin_lock(&mm->page_table_lock); 185 spin_lock(&mm->context.list_lock);
186 page = NULL; 186 page = NULL;
187 if (!list_empty(&mm->context.pgtable_list)) { 187 if (!list_empty(&mm->context.pgtable_list)) {
188 page = list_first_entry(&mm->context.pgtable_list, 188 page = list_first_entry(&mm->context.pgtable_list,
@@ -191,7 +191,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
191 page = NULL; 191 page = NULL;
192 } 192 }
193 if (!page) { 193 if (!page) {
194 spin_unlock(&mm->page_table_lock); 194 spin_unlock(&mm->context.list_lock);
195 page = alloc_page(GFP_KERNEL|__GFP_REPEAT); 195 page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
196 if (!page) 196 if (!page)
197 return NULL; 197 return NULL;
@@ -202,7 +202,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
202 clear_table_pgstes(table); 202 clear_table_pgstes(table);
203 else 203 else
204 clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); 204 clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
205 spin_lock(&mm->page_table_lock); 205 spin_lock(&mm->context.list_lock);
206 list_add(&page->lru, &mm->context.pgtable_list); 206 list_add(&page->lru, &mm->context.pgtable_list);
207 } 207 }
208 table = (unsigned long *) page_to_phys(page); 208 table = (unsigned long *) page_to_phys(page);
@@ -213,7 +213,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm)
213 page->flags |= bits; 213 page->flags |= bits;
214 if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) 214 if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
215 list_move_tail(&page->lru, &mm->context.pgtable_list); 215 list_move_tail(&page->lru, &mm->context.pgtable_list);
216 spin_unlock(&mm->page_table_lock); 216 spin_unlock(&mm->context.list_lock);
217 return table; 217 return table;
218} 218}
219 219
@@ -225,7 +225,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
225 bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; 225 bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
226 bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); 226 bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
227 page = pfn_to_page(__pa(table) >> PAGE_SHIFT); 227 page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
228 spin_lock(&mm->page_table_lock); 228 spin_lock(&mm->context.list_lock);
229 page->flags ^= bits; 229 page->flags ^= bits;
230 if (page->flags & FRAG_MASK) { 230 if (page->flags & FRAG_MASK) {
231 /* Page now has some free pgtable fragments. */ 231 /* Page now has some free pgtable fragments. */
@@ -234,7 +234,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
234 } else 234 } else
235 /* All fragments of the 4K page have been freed. */ 235 /* All fragments of the 4K page have been freed. */
236 list_del(&page->lru); 236 list_del(&page->lru);
237 spin_unlock(&mm->page_table_lock); 237 spin_unlock(&mm->context.list_lock);
238 if (page) { 238 if (page) {
239 pgtable_page_dtor(page); 239 pgtable_page_dtor(page);
240 __free_page(page); 240 __free_page(page);
@@ -245,7 +245,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk)
245{ 245{
246 struct page *page; 246 struct page *page;
247 247
248 spin_lock(&mm->page_table_lock); 248 spin_lock(&mm->context.list_lock);
249 /* Free shadow region and segment tables. */ 249 /* Free shadow region and segment tables. */
250 list_for_each_entry(page, &mm->context.crst_list, lru) 250 list_for_each_entry(page, &mm->context.crst_list, lru)
251 if (page->index) { 251 if (page->index) {
@@ -255,7 +255,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk)
255 /* "Free" second halves of page tables. */ 255 /* "Free" second halves of page tables. */
256 list_for_each_entry(page, &mm->context.pgtable_list, lru) 256 list_for_each_entry(page, &mm->context.pgtable_list, lru)
257 page->flags &= ~SECOND_HALVES; 257 page->flags &= ~SECOND_HALVES;
258 spin_unlock(&mm->page_table_lock); 258 spin_unlock(&mm->context.list_lock);
259 mm->context.noexec = 0; 259 mm->context.noexec = 0;
260 update_mm(mm, tsk); 260 update_mm(mm, tsk);
261} 261}
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index e4868bfc672f..5f91a38d7592 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -331,6 +331,7 @@ void __init vmem_map_init(void)
331 unsigned long start, end; 331 unsigned long start, end;
332 int i; 332 int i;
333 333
334 spin_lock_init(&init_mm.context.list_lock);
334 INIT_LIST_HEAD(&init_mm.context.crst_list); 335 INIT_LIST_HEAD(&init_mm.context.crst_list);
335 INIT_LIST_HEAD(&init_mm.context.pgtable_list); 336 INIT_LIST_HEAD(&init_mm.context.pgtable_list);
336 init_mm.context.noexec = 0; 337 init_mm.context.noexec = 0;
diff --git a/arch/s390/power/Makefile b/arch/s390/power/Makefile
deleted file mode 100644
index 973bb45a8fec..000000000000
--- a/arch/s390/power/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for s390 PM support
3#
4
5obj-$(CONFIG_HIBERNATION) += suspend.o
6obj-$(CONFIG_HIBERNATION) += swsusp.o
7obj-$(CONFIG_HIBERNATION) += swsusp_64.o
8obj-$(CONFIG_HIBERNATION) += swsusp_asm64.o
diff --git a/arch/s390/power/suspend.c b/arch/s390/power/suspend.c
deleted file mode 100644
index b3351eceebbe..000000000000
--- a/arch/s390/power/suspend.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Suspend support specific for s390.
3 *
4 * Copyright IBM Corp. 2009
5 *
6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com>
7 */
8
9#include <linux/mm.h>
10#include <linux/suspend.h>
11#include <linux/reboot.h>
12#include <linux/pfn.h>
13#include <asm/sections.h>
14#include <asm/ipl.h>
15
16/*
17 * References to section boundaries
18 */
19extern const void __nosave_begin, __nosave_end;
20
21/*
22 * check if given pfn is in the 'nosave' or in the read only NSS section
23 */
24int pfn_is_nosave(unsigned long pfn)
25{
26 unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
27 unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end))
28 >> PAGE_SHIFT;
29 unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
30 unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
31
32 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
33 return 1;
34 if (pfn >= stext_pfn && pfn <= eshared_pfn) {
35 if (ipl_info.type == IPL_TYPE_NSS)
36 return 1;
37 } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0))
38 return 1;
39 return 0;
40}
diff --git a/arch/s390/power/swsusp_64.c b/arch/s390/power/swsusp_64.c
deleted file mode 100644
index 9516a517d72f..000000000000
--- a/arch/s390/power/swsusp_64.c
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * Support for suspend and resume on s390
3 *
4 * Copyright IBM Corp. 2009
5 *
6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com>
7 *
8 */
9
10#include <asm/system.h>
11#include <linux/interrupt.h>
12
13void do_after_copyback(void)
14{
15 mb();
16}
17
diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index bb832584f3c1..acf99700deed 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -6,6 +6,9 @@ enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
6struct sh_eth_plat_data { 6struct sh_eth_plat_data {
7 int phy; 7 int phy;
8 int edmac_endian; 8 int edmac_endian;
9
10 unsigned no_ether_link:1;
11 unsigned ether_link_active_low:1;
9}; 12};
10 13
11#endif 14#endif
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index b5afbec1db59..04a21883f327 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -640,5 +640,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
640 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 640 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
641 clear_thread_flag(TIF_NOTIFY_RESUME); 641 clear_thread_flag(TIF_NOTIFY_RESUME);
642 tracehook_notify_resume(regs); 642 tracehook_notify_resume(regs);
643 if (current->replacement_session_keyring)
644 key_replace_session_keyring();
643 } 645 }
644} 646}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 0663a0ee6021..9e5c9b1d7e98 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -772,5 +772,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info
772 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 772 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
773 clear_thread_flag(TIF_NOTIFY_RESUME); 773 clear_thread_flag(TIF_NOTIFY_RESUME);
774 tracehook_notify_resume(regs); 774 tracehook_notify_resume(regs);
775 if (current->replacement_session_keyring)
776 key_replace_session_keyring();
775 } 777 }
776} 778}
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 3f8b6a92eabd..2bd5c287538a 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -25,6 +25,9 @@ config SPARC
25 select ARCH_WANT_OPTIONAL_GPIOLIB 25 select ARCH_WANT_OPTIONAL_GPIOLIB
26 select RTC_CLASS 26 select RTC_CLASS
27 select RTC_DRV_M48T59 27 select RTC_DRV_M48T59
28 select HAVE_PERF_COUNTERS
29 select HAVE_DMA_ATTRS
30 select HAVE_DMA_API_DEBUG
28 31
29config SPARC32 32config SPARC32
30 def_bool !64BIT 33 def_bool !64BIT
@@ -44,6 +47,7 @@ config SPARC64
44 select RTC_DRV_BQ4802 47 select RTC_DRV_BQ4802
45 select RTC_DRV_SUN4V 48 select RTC_DRV_SUN4V
46 select RTC_DRV_STARFIRE 49 select RTC_DRV_STARFIRE
50 select HAVE_PERF_COUNTERS
47 51
48config ARCH_DEFCONFIG 52config ARCH_DEFCONFIG
49 string 53 string
@@ -437,6 +441,17 @@ config SERIAL_CONSOLE
437 441
438 If unsure, say N. 442 If unsure, say N.
439 443
444config SPARC_LEON
445 bool "Sparc Leon processor family"
446 depends on SPARC32
447 ---help---
448 If you say Y here if you are running on a SPARC-LEON processor.
449 The LEON processor is a synthesizable VHDL model of the
450 SPARC-v8 standard. LEON is part of the GRLIB collection of
451 IP cores that are distributed under GPL. GRLIB can be downloaded
452 from www.gaisler.com. You can download a sparc-linux cross-compilation
453 toolchain at www.gaisler.com.
454
440endmenu 455endmenu
441 456
442menu "Bus options (PCI etc.)" 457menu "Bus options (PCI etc.)"
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 2003ded054c2..467221dd5702 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -38,10 +38,6 @@ CPPFLAGS_vmlinux.lds += -m32
38# Actual linking is done with "make image". 38# Actual linking is done with "make image".
39LDFLAGS_vmlinux = -r 39LDFLAGS_vmlinux = -r
40 40
41# Default target
42all: zImage
43
44
45else 41else
46##### 42#####
47# sparc64 43# sparc64
@@ -91,6 +87,9 @@ endif
91 87
92boot := arch/sparc/boot 88boot := arch/sparc/boot
93 89
90# Default target
91all: zImage
92
94image zImage tftpboot.img vmlinux.aout: vmlinux 93image zImage tftpboot.img vmlinux.aout: vmlinux
95 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 94 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
96 95
@@ -109,8 +108,9 @@ define archhelp
109endef 108endef
110else 109else
111define archhelp 110define archhelp
112 echo '* vmlinux - Standard sparc64 kernel' 111 echo '* vmlinux - standard sparc64 kernel'
113 echo ' vmlinux.aout - a.out kernel for sparc64' 112 echo '* zImage - stripped and compressed sparc64 kernel ($(boot)/zImage)'
113 echo ' vmlinux.aout - a.out kernel for sparc64'
114 echo ' tftpboot.img - image prepared for tftp' 114 echo ' tftpboot.img - image prepared for tftp'
115endef 115endef
116endif 116endif
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile
index 1ff0fd924756..97e3feb9ff1b 100644
--- a/arch/sparc/boot/Makefile
+++ b/arch/sparc/boot/Makefile
@@ -79,6 +79,9 @@ $(obj)/image: vmlinux FORCE
79 $(call if_changed,strip) 79 $(call if_changed,strip)
80 @echo ' kernel: $@ is ready' 80 @echo ' kernel: $@ is ready'
81 81
82$(obj)/zImage: $(obj)/image
83 $(call if_changed,gzip)
84
82$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE 85$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE
83 $(call if_changed,elftoaout) 86 $(call if_changed,elftoaout)
84 $(call if_changed,piggy) 87 $(call if_changed,piggy)
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h
index 74703c5ef985..b2e3db63a64b 100644
--- a/arch/sparc/include/asm/asi.h
+++ b/arch/sparc/include/asm/asi.h
@@ -40,7 +40,11 @@
40#define ASI_M_UNA01 0x01 /* Same here... */ 40#define ASI_M_UNA01 0x01 /* Same here... */
41#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ 41#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */
42#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ 42#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */
43#ifndef CONFIG_SPARC_LEON
43#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ 44#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */
45#else
46#define ASI_M_MMUREGS 0x19
47#endif /* CONFIG_SPARC_LEON */
44#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ 48#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */
45#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ 49#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */
46#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ 50#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */
diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h
index 3702e087df2c..f3b85b6b0b76 100644
--- a/arch/sparc/include/asm/device.h
+++ b/arch/sparc/include/asm/device.h
@@ -32,4 +32,7 @@ dev_archdata_get_node(const struct dev_archdata *ad)
32 return ad->prom_node; 32 return ad->prom_node;
33} 33}
34 34
35struct pdev_archdata {
36};
37
35#endif /* _ASM_SPARC_DEVICE_H */ 38#endif /* _ASM_SPARC_DEVICE_H */
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 204e4bf64438..5a8c308e2b5c 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/scatterlist.h> 4#include <linux/scatterlist.h>
5#include <linux/mm.h> 5#include <linux/mm.h>
6#include <linux/dma-debug.h>
6 7
7#define DMA_ERROR_CODE (~(dma_addr_t)0x0) 8#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
8 9
@@ -13,142 +14,40 @@ extern int dma_set_mask(struct device *dev, u64 dma_mask);
13#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 14#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
14#define dma_is_consistent(d, h) (1) 15#define dma_is_consistent(d, h) (1)
15 16
16struct dma_ops { 17extern struct dma_map_ops *dma_ops, pci32_dma_ops;
17 void *(*alloc_coherent)(struct device *dev, size_t size, 18extern struct bus_type pci_bus_type;
18 dma_addr_t *dma_handle, gfp_t flag);
19 void (*free_coherent)(struct device *dev, size_t size,
20 void *cpu_addr, dma_addr_t dma_handle);
21 dma_addr_t (*map_page)(struct device *dev, struct page *page,
22 unsigned long offset, size_t size,
23 enum dma_data_direction direction);
24 void (*unmap_page)(struct device *dev, dma_addr_t dma_addr,
25 size_t size,
26 enum dma_data_direction direction);
27 int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents,
28 enum dma_data_direction direction);
29 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
30 int nhwentries,
31 enum dma_data_direction direction);
32 void (*sync_single_for_cpu)(struct device *dev,
33 dma_addr_t dma_handle, size_t size,
34 enum dma_data_direction direction);
35 void (*sync_single_for_device)(struct device *dev,
36 dma_addr_t dma_handle, size_t size,
37 enum dma_data_direction direction);
38 void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg,
39 int nelems,
40 enum dma_data_direction direction);
41 void (*sync_sg_for_device)(struct device *dev,
42 struct scatterlist *sg, int nents,
43 enum dma_data_direction dir);
44};
45extern const struct dma_ops *dma_ops;
46 19
47static inline void *dma_alloc_coherent(struct device *dev, size_t size, 20static inline struct dma_map_ops *get_dma_ops(struct device *dev)
48 dma_addr_t *dma_handle, gfp_t flag)
49{
50 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
51}
52
53static inline void dma_free_coherent(struct device *dev, size_t size,
54 void *cpu_addr, dma_addr_t dma_handle)
55{
56 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
57}
58
59static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
60 size_t size,
61 enum dma_data_direction direction)
62{
63 return dma_ops->map_page(dev, virt_to_page(cpu_addr),
64 (unsigned long)cpu_addr & ~PAGE_MASK, size,
65 direction);
66}
67
68static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
69 size_t size,
70 enum dma_data_direction direction)
71{
72 dma_ops->unmap_page(dev, dma_addr, size, direction);
73}
74
75static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
76 unsigned long offset, size_t size,
77 enum dma_data_direction direction)
78{
79 return dma_ops->map_page(dev, page, offset, size, direction);
80}
81
82static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
83 size_t size,
84 enum dma_data_direction direction)
85{
86 dma_ops->unmap_page(dev, dma_address, size, direction);
87}
88
89static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
90 int nents, enum dma_data_direction direction)
91{
92 return dma_ops->map_sg(dev, sg, nents, direction);
93}
94
95static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
96 int nents, enum dma_data_direction direction)
97{ 21{
98 dma_ops->unmap_sg(dev, sg, nents, direction); 22#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
99} 23 if (dev->bus == &pci_bus_type)
100 24 return &pci32_dma_ops;
101static inline void dma_sync_single_for_cpu(struct device *dev, 25#endif
102 dma_addr_t dma_handle, size_t size, 26 return dma_ops;
103 enum dma_data_direction direction)
104{
105 dma_ops->sync_single_for_cpu(dev, dma_handle, size, direction);
106} 27}
107 28
108static inline void dma_sync_single_for_device(struct device *dev, 29#include <asm-generic/dma-mapping-common.h>
109 dma_addr_t dma_handle,
110 size_t size,
111 enum dma_data_direction direction)
112{
113 if (dma_ops->sync_single_for_device)
114 dma_ops->sync_single_for_device(dev, dma_handle, size,
115 direction);
116}
117 30
118static inline void dma_sync_sg_for_cpu(struct device *dev, 31static inline void *dma_alloc_coherent(struct device *dev, size_t size,
119 struct scatterlist *sg, int nelems, 32 dma_addr_t *dma_handle, gfp_t flag)
120 enum dma_data_direction direction)
121{ 33{
122 dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction); 34 struct dma_map_ops *ops = get_dma_ops(dev);
123} 35 void *cpu_addr;
124 36
125static inline void dma_sync_sg_for_device(struct device *dev, 37 cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag);
126 struct scatterlist *sg, int nelems, 38 debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
127 enum dma_data_direction direction) 39 return cpu_addr;
128{
129 if (dma_ops->sync_sg_for_device)
130 dma_ops->sync_sg_for_device(dev, sg, nelems, direction);
131} 40}
132 41
133static inline void dma_sync_single_range_for_cpu(struct device *dev, 42static inline void dma_free_coherent(struct device *dev, size_t size,
134 dma_addr_t dma_handle, 43 void *cpu_addr, dma_addr_t dma_handle)
135 unsigned long offset,
136 size_t size,
137 enum dma_data_direction dir)
138{ 44{
139 dma_sync_single_for_cpu(dev, dma_handle+offset, size, dir); 45 struct dma_map_ops *ops = get_dma_ops(dev);
140}
141 46
142static inline void dma_sync_single_range_for_device(struct device *dev, 47 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
143 dma_addr_t dma_handle, 48 ops->free_coherent(dev, size, cpu_addr, dma_handle);
144 unsigned long offset,
145 size_t size,
146 enum dma_data_direction dir)
147{
148 dma_sync_single_for_device(dev, dma_handle+offset, size, dir);
149} 49}
150 50
151
152static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 51static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
153{ 52{
154 return (dma_addr == DMA_ERROR_CODE); 53 return (dma_addr == DMA_ERROR_CODE);
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h
index 1934f2cbf513..a0b443cb3c1f 100644
--- a/arch/sparc/include/asm/irq_64.h
+++ b/arch/sparc/include/asm/irq_64.h
@@ -89,8 +89,8 @@ static inline unsigned long get_softint(void)
89 return retval; 89 return retval;
90} 90}
91 91
92void __trigger_all_cpu_backtrace(void); 92void arch_trigger_all_cpu_backtrace(void);
93#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() 93#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
94 94
95extern void *hardirq_stack[NR_CPUS]; 95extern void *hardirq_stack[NR_CPUS];
96extern void *softirq_stack[NR_CPUS]; 96extern void *softirq_stack[NR_CPUS];
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
new file mode 100644
index 000000000000..28a42b73f64f
--- /dev/null
+++ b/arch/sparc/include/asm/leon.h
@@ -0,0 +1,362 @@
1/*
2 * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com) Gaisler Research
3 * Copyright (C) 2004 Stefan Holst (mail@s-holst.de) Uni-Stuttgart
4 * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
5 * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
6 */
7
8#ifndef LEON_H_INCLUDE
9#define LEON_H_INCLUDE
10
11#ifdef CONFIG_SPARC_LEON
12
13#define ASI_LEON_NOCACHE 0x01
14
15#define ASI_LEON_DCACHE_MISS 0x1
16
17#define ASI_LEON_CACHEREGS 0x02
18#define ASI_LEON_IFLUSH 0x10
19#define ASI_LEON_DFLUSH 0x11
20
21#define ASI_LEON_MMUFLUSH 0x18
22#define ASI_LEON_MMUREGS 0x19
23#define ASI_LEON_BYPASS 0x1c
24#define ASI_LEON_FLUSH_PAGE 0x10
25
26/* mmu register access, ASI_LEON_MMUREGS */
27#define LEON_CNR_CTRL 0x000
28#define LEON_CNR_CTXP 0x100
29#define LEON_CNR_CTX 0x200
30#define LEON_CNR_F 0x300
31#define LEON_CNR_FADDR 0x400
32
33#define LEON_CNR_CTX_NCTX 256 /*number of MMU ctx */
34
35#define LEON_CNR_CTRL_TLBDIS 0x80000000
36
37#define LEON_MMUTLB_ENT_MAX 64
38
39/*
40 * diagnostic access from mmutlb.vhd:
41 * 0: pte address
42 * 4: pte
43 * 8: additional flags
44 */
45#define LEON_DIAGF_LVL 0x3
46#define LEON_DIAGF_WR 0x8
47#define LEON_DIAGF_WR_SHIFT 3
48#define LEON_DIAGF_HIT 0x10
49#define LEON_DIAGF_HIT_SHIFT 4
50#define LEON_DIAGF_CTX 0x1fe0
51#define LEON_DIAGF_CTX_SHIFT 5
52#define LEON_DIAGF_VALID 0x2000
53#define LEON_DIAGF_VALID_SHIFT 13
54
55/*
56 * Interrupt Sources
57 *
58 * The interrupt source numbers directly map to the trap type and to
59 * the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
60 * and the Interrupt Pending Registers.
61 */
62#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR 1
63#define LEON_INTERRUPT_UART_1_RX_TX 2
64#define LEON_INTERRUPT_UART_0_RX_TX 3
65#define LEON_INTERRUPT_EXTERNAL_0 4
66#define LEON_INTERRUPT_EXTERNAL_1 5
67#define LEON_INTERRUPT_EXTERNAL_2 6
68#define LEON_INTERRUPT_EXTERNAL_3 7
69#define LEON_INTERRUPT_TIMER1 8
70#define LEON_INTERRUPT_TIMER2 9
71#define LEON_INTERRUPT_EMPTY1 10
72#define LEON_INTERRUPT_EMPTY2 11
73#define LEON_INTERRUPT_OPEN_ETH 12
74#define LEON_INTERRUPT_EMPTY4 13
75#define LEON_INTERRUPT_EMPTY5 14
76#define LEON_INTERRUPT_EMPTY6 15
77
78/* irq masks */
79#define LEON_HARD_INT(x) (1 << (x)) /* irq 0-15 */
80#define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */
81#define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */
82
83/* leon uart register definitions */
84#define LEON_OFF_UDATA 0x0
85#define LEON_OFF_USTAT 0x4
86#define LEON_OFF_UCTRL 0x8
87#define LEON_OFF_USCAL 0xc
88
89#define LEON_UCTRL_RE 0x01
90#define LEON_UCTRL_TE 0x02
91#define LEON_UCTRL_RI 0x04
92#define LEON_UCTRL_TI 0x08
93#define LEON_UCTRL_PS 0x10
94#define LEON_UCTRL_PE 0x20
95#define LEON_UCTRL_FL 0x40
96#define LEON_UCTRL_LB 0x80
97
98#define LEON_USTAT_DR 0x01
99#define LEON_USTAT_TS 0x02
100#define LEON_USTAT_TH 0x04
101#define LEON_USTAT_BR 0x08
102#define LEON_USTAT_OV 0x10
103#define LEON_USTAT_PE 0x20
104#define LEON_USTAT_FE 0x40
105
106#define LEON_MCFG2_SRAMDIS 0x00002000
107#define LEON_MCFG2_SDRAMEN 0x00004000
108#define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */
109#define LEON_MCFG2_SRAMBANKSZ_SHIFT 9
110#define LEON_MCFG2_SDRAMBANKSZ 0x03800000 /* [25-23] */
111#define LEON_MCFG2_SDRAMBANKSZ_SHIFT 23
112
113#define LEON_TCNT0_MASK 0x7fffff
114
115#define LEON_USTAT_ERROR (LEON_USTAT_OV | LEON_USTAT_PE | LEON_USTAT_FE)
116/* no break yet */
117
118#define ASI_LEON3_SYSCTRL 0x02
119#define ASI_LEON3_SYSCTRL_ICFG 0x08
120#define ASI_LEON3_SYSCTRL_DCFG 0x0c
121#define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1 << 27)
122#define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1 << ((c >> 20) & 0xf))
123
124#ifndef __ASSEMBLY__
125
126/* do a virtual address read without cache */
127static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
128{
129 unsigned long retval;
130 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
131 "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
132 return retval;
133}
134
135/* do a physical address bypass write, i.e. for 0x80000000 */
136static inline void leon_store_reg(unsigned long paddr, unsigned long value)
137{
138 __asm__ __volatile__("sta %0, [%1] %2\n\t" : : "r"(value), "r"(paddr),
139 "i"(ASI_LEON_BYPASS) : "memory");
140}
141
142/* do a physical address bypass load, i.e. for 0x80000000 */
143static inline unsigned long leon_load_reg(unsigned long paddr)
144{
145 unsigned long retval;
146 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
147 "=r"(retval) : "r"(paddr), "i"(ASI_LEON_BYPASS));
148 return retval;
149}
150
151extern inline void leon_srmmu_disabletlb(void)
152{
153 unsigned int retval;
154 __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
155 "i"(ASI_LEON_MMUREGS));
156 retval |= LEON_CNR_CTRL_TLBDIS;
157 __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
158 "i"(ASI_LEON_MMUREGS) : "memory");
159}
160
161extern inline void leon_srmmu_enabletlb(void)
162{
163 unsigned int retval;
164 __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
165 "i"(ASI_LEON_MMUREGS));
166 retval = retval & ~LEON_CNR_CTRL_TLBDIS;
167 __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
168 "i"(ASI_LEON_MMUREGS) : "memory");
169}
170
171/* macro access for leon_load_reg() and leon_store_reg() */
172#define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x)))
173#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
174#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
175#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
176#define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x))
177#define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v))
178#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS)
179#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
180#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
181#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))
182
183/* macro access for leon_readnobuffer_reg() */
184#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
185
186extern void sparc_leon_eirq_register(int eirq);
187extern void leon_init(void);
188extern void leon_switch_mm(void);
189extern void leon_init_IRQ(void);
190
191extern unsigned long last_valid_pfn;
192
193extern inline unsigned long sparc_leon3_get_dcachecfg(void)
194{
195 unsigned int retval;
196 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
197 "=r"(retval) :
198 "r"(ASI_LEON3_SYSCTRL_DCFG),
199 "i"(ASI_LEON3_SYSCTRL));
200 return retval;
201}
202
203/* enable snooping */
204extern inline void sparc_leon3_enable_snooping(void)
205{
206 __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
207 "set 0x800000, %%l2\n\t"
208 "or %%l2, %%l1, %%l2\n\t"
209 "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
210};
211
212extern inline void sparc_leon3_disable_cache(void)
213{
214 __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
215 "set 0x00000f, %%l2\n\t"
216 "andn %%l2, %%l1, %%l2\n\t"
217 "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
218};
219
220#endif /*!__ASSEMBLY__*/
221
222#ifdef CONFIG_SMP
223# define LEON3_IRQ_RESCHEDULE 13
224# define LEON3_IRQ_TICKER (leon_percpu_timer_dev[0].irq)
225# define LEON3_IRQ_CROSS_CALL 15
226#endif
227
228#if defined(PAGE_SIZE_LEON_8K)
229#define LEON_PAGE_SIZE_LEON 1
230#elif defined(PAGE_SIZE_LEON_16K)
231#define LEON_PAGE_SIZE_LEON 2)
232#else
233#define LEON_PAGE_SIZE_LEON 0
234#endif
235
236#if LEON_PAGE_SIZE_LEON == 0
237/* [ 8, 6, 6 ] + 12 */
238#define LEON_PGD_SH 24
239#define LEON_PGD_M 0xff
240#define LEON_PMD_SH 18
241#define LEON_PMD_SH_V (LEON_PGD_SH-2)
242#define LEON_PMD_M 0x3f
243#define LEON_PTE_SH 12
244#define LEON_PTE_M 0x3f
245#elif LEON_PAGE_SIZE_LEON == 1
246/* [ 7, 6, 6 ] + 13 */
247#define LEON_PGD_SH 25
248#define LEON_PGD_M 0x7f
249#define LEON_PMD_SH 19
250#define LEON_PMD_SH_V (LEON_PGD_SH-1)
251#define LEON_PMD_M 0x3f
252#define LEON_PTE_SH 13
253#define LEON_PTE_M 0x3f
254#elif LEON_PAGE_SIZE_LEON == 2
255/* [ 6, 6, 6 ] + 14 */
256#define LEON_PGD_SH 26
257#define LEON_PGD_M 0x3f
258#define LEON_PMD_SH 20
259#define LEON_PMD_SH_V (LEON_PGD_SH-0)
260#define LEON_PMD_M 0x3f
261#define LEON_PTE_SH 14
262#define LEON_PTE_M 0x3f
263#elif LEON_PAGE_SIZE_LEON == 3
264/* [ 4, 7, 6 ] + 15 */
265#define LEON_PGD_SH 28
266#define LEON_PGD_M 0x0f
267#define LEON_PMD_SH 21
268#define LEON_PMD_SH_V (LEON_PGD_SH-0)
269#define LEON_PMD_M 0x7f
270#define LEON_PTE_SH 15
271#define LEON_PTE_M 0x3f
272#else
273#error cannot determine LEON_PAGE_SIZE_LEON
274#endif
275
276#define PAGE_MIN_SHIFT (12)
277#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT)
278
279#define LEON3_XCCR_SETS_MASK 0x07000000UL
280#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL
281
282#define LEON2_CCR_DSETS_MASK 0x03000000UL
283#define LEON2_CFG_SSIZE_MASK 0x00007000UL
284
285#ifndef __ASSEMBLY__
286extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
287extern void leon_flush_icache_all(void);
288extern void leon_flush_dcache_all(void);
289extern void leon_flush_cache_all(void);
290extern void leon_flush_tlb_all(void);
291extern int leon_flush_during_switch;
292extern int leon_flush_needed(void);
293
294struct vm_area_struct;
295extern void leon_flush_icache_all(void);
296extern void leon_flush_dcache_all(void);
297extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
298extern void leon_flush_cache_all(void);
299extern void leon_flush_tlb_all(void);
300extern int leon_flush_during_switch;
301extern int leon_flush_needed(void);
302extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
303
304/* struct that hold LEON3 cache configuration registers */
305struct leon3_cacheregs {
306 unsigned long ccr; /* 0x00 - Cache Control Register */
307 unsigned long iccr; /* 0x08 - Instruction Cache Configuration Register */
308 unsigned long dccr; /* 0x0c - Data Cache Configuration Register */
309};
310
311/* struct that hold LEON2 cache configuration register
312 * & configuration register
313 */
314struct leon2_cacheregs {
315 unsigned long ccr, cfg;
316};
317
318#ifdef __KERNEL__
319
320#include <linux/interrupt.h>
321
322struct device_node;
323extern int sparc_leon_eirq_get(int eirq, int cpu);
324extern irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id);
325extern void sparc_leon_eirq_register(int eirq);
326extern void leon_clear_clock_irq(void);
327extern void leon_load_profile_irq(int cpu, unsigned int limit);
328extern void leon_init_timers(irq_handler_t counter_fn);
329extern void leon_clear_clock_irq(void);
330extern void leon_load_profile_irq(int cpu, unsigned int limit);
331extern void leon_trans_init(struct device_node *dp);
332extern void leon_node_init(struct device_node *dp, struct device_node ***nextp);
333extern void leon_init_IRQ(void);
334extern void leon_init(void);
335extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
336extern void init_leon(void);
337extern void poke_leonsparc(void);
338extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
339extern int leon_flush_needed(void);
340extern void leon_switch_mm(void);
341extern int srmmu_swprobe_trace;
342
343#endif /* __KERNEL__ */
344
345#endif /* __ASSEMBLY__ */
346
347/* macros used in leon_mm.c */
348#define PFN(x) ((x) >> PAGE_SHIFT)
349#define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
350#define _SRMMU_PTE_PMASK_LEON 0xffffffff
351
352#else /* defined(CONFIG_SPARC_LEON) */
353
354/* nop definitions for !LEON case */
355#define leon_init() do {} while (0)
356#define leon_switch_mm() do {} while (0)
357#define leon_init_IRQ() do {} while (0)
358#define init_leon() do {} while (0)
359
360#endif /* !defined(CONFIG_SPARC_LEON) */
361
362#endif
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h
new file mode 100644
index 000000000000..618e88821795
--- /dev/null
+++ b/arch/sparc/include/asm/leon_amba.h
@@ -0,0 +1,263 @@
1/*
2*Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com), Gaisler Research
3*Copyright (C) 2004 Stefan Holst (mail@s-holst.de), Uni-Stuttgart
4*Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com),Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
5*/
6
7#ifndef LEON_AMBA_H_INCLUDE
8#define LEON_AMBA_H_INCLUDE
9
10#ifndef __ASSEMBLY__
11
12struct amba_prom_registers {
13 unsigned int phys_addr; /* The physical address of this register */
14 unsigned int reg_size; /* How many bytes does this register take up? */
15};
16
17#endif
18
19/*
20 * The following defines the bits in the LEON UART Status Registers.
21 */
22
23#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
24#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
25#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
26#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
27#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
28#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
29#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
30#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
31
32/*
33 * The following defines the bits in the LEON UART Ctrl Registers.
34 */
35
36#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
37#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
38#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
39#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter irq */
40#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
41#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
42#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
43#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
44
45#define LEON3_GPTIMER_EN 1
46#define LEON3_GPTIMER_RL 2
47#define LEON3_GPTIMER_LD 4
48#define LEON3_GPTIMER_IRQEN 8
49#define LEON3_GPTIMER_SEPIRQ 8
50
51#define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */
52/* 0 = hold scalar and counter */
53#define LEON23_REG_TIMER_CONTROL_RL 0x00000002 /* 1 = reload at 0 */
54 /* 0 = stop at 0 */
55#define LEON23_REG_TIMER_CONTROL_LD 0x00000004 /* 1 = load counter */
56 /* 0 = no function */
57#define LEON23_REG_TIMER_CONTROL_IQ 0x00000008 /* 1 = irq enable */
58 /* 0 = no function */
59
60/*
61 * The following defines the bits in the LEON PS/2 Status Registers.
62 */
63
64#define LEON_REG_PS2_STATUS_DR 0x00000001 /* Data Ready */
65#define LEON_REG_PS2_STATUS_PE 0x00000002 /* Parity error */
66#define LEON_REG_PS2_STATUS_FE 0x00000004 /* Framing error */
67#define LEON_REG_PS2_STATUS_KI 0x00000008 /* Keyboard inhibit */
68#define LEON_REG_PS2_STATUS_RF 0x00000010 /* RX buffer full */
69#define LEON_REG_PS2_STATUS_TF 0x00000020 /* TX buffer full */
70
71/*
72 * The following defines the bits in the LEON PS/2 Ctrl Registers.
73 */
74
75#define LEON_REG_PS2_CTRL_RE 0x00000001 /* Receiver enable */
76#define LEON_REG_PS2_CTRL_TE 0x00000002 /* Transmitter enable */
77#define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive irq */
78#define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit irq */
79
80#define LEON3_IRQMPSTATUS_CPUNR 28
81#define LEON3_IRQMPSTATUS_BROADCAST 27
82
83#define GPTIMER_CONFIG_IRQNT(a) (((a) >> 3) & 0x1f)
84#define GPTIMER_CONFIG_ISSEP(a) ((a) & (1 << 8))
85#define GPTIMER_CONFIG_NTIMERS(a) ((a) & (0x7))
86#define LEON3_GPTIMER_CTRL_PENDING 0x10
87#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7)
88#define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0)
89
90#ifdef CONFIG_SPARC_LEON
91
92#ifndef __ASSEMBLY__
93
94struct leon3_irqctrl_regs_map {
95 u32 ilevel;
96 u32 ipend;
97 u32 iforce;
98 u32 iclear;
99 u32 mpstatus;
100 u32 mpbroadcast;
101 u32 notused02;
102 u32 notused03;
103 u32 notused10;
104 u32 notused11;
105 u32 notused12;
106 u32 notused13;
107 u32 notused20;
108 u32 notused21;
109 u32 notused22;
110 u32 notused23;
111 u32 mask[16];
112 u32 force[16];
113 /* Extended IRQ registers */
114 u32 intid[16]; /* 0xc0 */
115};
116
117struct leon3_apbuart_regs_map {
118 u32 data;
119 u32 status;
120 u32 ctrl;
121 u32 scaler;
122};
123
124struct leon3_gptimerelem_regs_map {
125 u32 val;
126 u32 rld;
127 u32 ctrl;
128 u32 unused;
129};
130
131struct leon3_gptimer_regs_map {
132 u32 scalar;
133 u32 scalar_reload;
134 u32 config;
135 u32 unused;
136 struct leon3_gptimerelem_regs_map e[8];
137};
138
139/*
140 * Types and structure used for AMBA Plug & Play bus scanning
141 */
142
143#define AMBA_MAXAPB_DEVS 64
144#define AMBA_MAXAPB_DEVS_PERBUS 16
145
146struct amba_device_table {
147 int devnr; /* number of devices on AHB or APB bus */
148 unsigned int *addr[16]; /* addresses to the devices configuration tables */
149 unsigned int allocbits[1]; /* 0=unallocated, 1=allocated driver */
150};
151
152struct amba_apbslv_device_table {
153 int devnr; /* number of devices on AHB or APB bus */
154 unsigned int *addr[AMBA_MAXAPB_DEVS]; /* addresses to the devices configuration tables */
155 unsigned int apbmst[AMBA_MAXAPB_DEVS]; /* apb master if a entry is a apb slave */
156 unsigned int apbmstidx[AMBA_MAXAPB_DEVS]; /* apb master idx if a entry is a apb slave */
157 unsigned int allocbits[4]; /* 0=unallocated, 1=allocated driver */
158};
159
160struct amba_confarea_type {
161 struct amba_confarea_type *next;/* next bus in chain */
162 struct amba_device_table ahbmst;
163 struct amba_device_table ahbslv;
164 struct amba_apbslv_device_table apbslv;
165 unsigned int apbmst;
166};
167
168/* collect apb slaves */
169struct amba_apb_device {
170 unsigned int start, irq, bus_id;
171 struct amba_confarea_type *bus;
172};
173
174/* collect ahb slaves */
175struct amba_ahb_device {
176 unsigned int start[4], irq, bus_id;
177 struct amba_confarea_type *bus;
178};
179
180struct device_node;
181void _amba_init(struct device_node *dp, struct device_node ***nextp);
182
183extern struct leon3_irqctrl_regs_map *leon3_irqctrl_regs;
184extern struct leon3_gptimer_regs_map *leon3_gptimer_regs;
185extern struct amba_apb_device leon_percpu_timer_dev[16];
186extern int leondebug_irq_disable;
187extern int leon_debug_irqout;
188extern unsigned long leon3_gptimer_irq;
189extern unsigned int sparc_leon_eirq;
190
191#endif /* __ASSEMBLY__ */
192
193#define LEON3_IO_AREA 0xfff00000
194#define LEON3_CONF_AREA 0xff000
195#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
196
197#define LEON3_AHB_CONF_WORDS 8
198#define LEON3_APB_CONF_WORDS 2
199#define LEON3_AHB_MASTERS 16
200#define LEON3_AHB_SLAVES 16
201#define LEON3_APB_SLAVES 16
202#define LEON3_APBUARTS 8
203
204/* Vendor codes */
205#define VENDOR_GAISLER 1
206#define VENDOR_PENDER 2
207#define VENDOR_ESA 4
208#define VENDOR_OPENCORES 8
209
210/* Gaisler Research device id's */
211#define GAISLER_LEON3 0x003
212#define GAISLER_LEON3DSU 0x004
213#define GAISLER_ETHAHB 0x005
214#define GAISLER_APBMST 0x006
215#define GAISLER_AHBUART 0x007
216#define GAISLER_SRCTRL 0x008
217#define GAISLER_SDCTRL 0x009
218#define GAISLER_APBUART 0x00C
219#define GAISLER_IRQMP 0x00D
220#define GAISLER_AHBRAM 0x00E
221#define GAISLER_GPTIMER 0x011
222#define GAISLER_PCITRG 0x012
223#define GAISLER_PCISBRG 0x013
224#define GAISLER_PCIFBRG 0x014
225#define GAISLER_PCITRACE 0x015
226#define GAISLER_PCIDMA 0x016
227#define GAISLER_AHBTRACE 0x017
228#define GAISLER_ETHDSU 0x018
229#define GAISLER_PIOPORT 0x01A
230#define GAISLER_GRGPIO 0x01A
231#define GAISLER_AHBJTAG 0x01c
232#define GAISLER_ETHMAC 0x01D
233#define GAISLER_AHB2AHB 0x020
234#define GAISLER_USBDC 0x021
235#define GAISLER_ATACTRL 0x024
236#define GAISLER_DDRSPA 0x025
237#define GAISLER_USBEHC 0x026
238#define GAISLER_USBUHC 0x027
239#define GAISLER_I2CMST 0x028
240#define GAISLER_SPICTRL 0x02D
241#define GAISLER_DDR2SPA 0x02E
242#define GAISLER_SPIMCTRL 0x045
243#define GAISLER_LEON4 0x048
244#define GAISLER_LEON4DSU 0x049
245#define GAISLER_AHBSTAT 0x052
246#define GAISLER_FTMCTRL 0x054
247#define GAISLER_KBD 0x060
248#define GAISLER_VGA 0x061
249#define GAISLER_SVGA 0x063
250#define GAISLER_GRSYSMON 0x066
251#define GAISLER_GRACECTRL 0x067
252
253#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */
254#define GAISLER_L2C 0xffe /* internal device: leon2compat */
255#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */
256
257#define amba_vendor(x) (((x) >> 24) & 0xff)
258
259#define amba_device(x) (((x) >> 12) & 0xfff)
260
261#endif /* !defined(CONFIG_SPARC_LEON) */
262
263#endif
diff --git a/arch/sparc/include/asm/machines.h b/arch/sparc/include/asm/machines.h
index c28c2f248794..cd9c099567e4 100644
--- a/arch/sparc/include/asm/machines.h
+++ b/arch/sparc/include/asm/machines.h
@@ -15,7 +15,7 @@ struct Sun_Machine_Models {
15/* Current number of machines we know about that has an IDPROM 15/* Current number of machines we know about that has an IDPROM
16 * machtype entry including one entry for the 0x80 OBP machines. 16 * machtype entry including one entry for the 0x80 OBP machines.
17 */ 17 */
18#define NUM_SUN_MACHINES 15 18#define NUM_SUN_MACHINES 16
19 19
20/* The machine type in the idprom area looks like this: 20/* The machine type in the idprom area looks like this:
21 * 21 *
@@ -30,6 +30,7 @@ struct Sun_Machine_Models {
30 30
31#define SM_ARCH_MASK 0xf0 31#define SM_ARCH_MASK 0xf0
32#define SM_SUN4 0x20 32#define SM_SUN4 0x20
33#define M_LEON 0x30
33#define SM_SUN4C 0x50 34#define SM_SUN4C 0x50
34#define SM_SUN4M 0x70 35#define SM_SUN4M 0x70
35#define SM_SUN4M_OBP 0x80 36#define SM_SUN4M_OBP 0x80
@@ -41,6 +42,9 @@ struct Sun_Machine_Models {
41#define SM_4_330 0x03 /* Sun 4/300 series */ 42#define SM_4_330 0x03 /* Sun 4/300 series */
42#define SM_4_470 0x04 /* Sun 4/400 series */ 43#define SM_4_470 0x04 /* Sun 4/400 series */
43 44
45/* Leon machines */
46#define M_LEON3_SOC 0x02 /* Leon3 SoC */
47
44/* Sun4c machines Full Name - PROM NAME */ 48/* Sun4c machines Full Name - PROM NAME */
45#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ 49#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */
46#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ 50#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */
diff --git a/arch/sparc/include/asm/nmi.h b/arch/sparc/include/asm/nmi.h
index fbd546dd4feb..72e6500e7ab0 100644
--- a/arch/sparc/include/asm/nmi.h
+++ b/arch/sparc/include/asm/nmi.h
@@ -5,6 +5,9 @@ extern int __init nmi_init(void);
5extern void perfctr_irq(int irq, struct pt_regs *regs); 5extern void perfctr_irq(int irq, struct pt_regs *regs);
6extern void nmi_adjust_hz(unsigned int new_hz); 6extern void nmi_adjust_hz(unsigned int new_hz);
7 7
8extern int nmi_usable; 8extern atomic_t nmi_active;
9
10extern void start_nmi_watchdog(void *unused);
11extern void stop_nmi_watchdog(void *unused);
9 12
10#endif /* __NMI_H */ 13#endif /* __NMI_H */
diff --git a/arch/sparc/include/asm/pci.h b/arch/sparc/include/asm/pci.h
index 6e14fd179335..d9c031f9910f 100644
--- a/arch/sparc/include/asm/pci.h
+++ b/arch/sparc/include/asm/pci.h
@@ -5,4 +5,7 @@
5#else 5#else
6#include <asm/pci_32.h> 6#include <asm/pci_32.h>
7#endif 7#endif
8
9#include <asm-generic/pci-dma-compat.h>
10
8#endif 11#endif
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index b41c4c198159..ac0e8369fd97 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -31,42 +31,8 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
31 */ 31 */
32#define PCI_DMA_BUS_IS_PHYS (0) 32#define PCI_DMA_BUS_IS_PHYS (0)
33 33
34#include <asm/scatterlist.h>
35
36struct pci_dev; 34struct pci_dev;
37 35
38/* Allocate and map kernel buffer using consistent mode DMA for a device.
39 * hwdev should be valid struct pci_dev pointer for PCI devices.
40 */
41extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
42
43/* Free and unmap a consistent DMA buffer.
44 * cpu_addr is what was returned from pci_alloc_consistent,
45 * size must be the same as what as passed into pci_alloc_consistent,
46 * and likewise dma_addr must be the same as what *dma_addrp was set to.
47 *
48 * References to the memory and mappings assosciated with cpu_addr/dma_addr
49 * past this call are illegal.
50 */
51extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
52
53/* Map a single buffer of the indicated size for DMA in streaming mode.
54 * The 32-bit bus address to use is returned.
55 *
56 * Once the device is given the dma address, the device owns this memory
57 * until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed.
58 */
59extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction);
60
61/* Unmap a single streaming mode DMA translation. The dma_addr and size
62 * must match what was provided for in a previous pci_map_single call. All
63 * other usages are undefined.
64 *
65 * After this call, reads by the cpu to the buffer are guaranteed to see
66 * whatever the device wrote there.
67 */
68extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
69
70/* pci_unmap_{single,page} is not a nop, thus... */ 36/* pci_unmap_{single,page} is not a nop, thus... */
71#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ 37#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
72 dma_addr_t ADDR_NAME; 38 dma_addr_t ADDR_NAME;
@@ -81,69 +47,6 @@ extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t
81#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ 47#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
82 (((PTR)->LEN_NAME) = (VAL)) 48 (((PTR)->LEN_NAME) = (VAL))
83 49
84/*
85 * Same as above, only with pages instead of mapped addresses.
86 */
87extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
88 unsigned long offset, size_t size, int direction);
89extern void pci_unmap_page(struct pci_dev *hwdev,
90 dma_addr_t dma_address, size_t size, int direction);
91
92/* Map a set of buffers described by scatterlist in streaming
93 * mode for DMA. This is the scather-gather version of the
94 * above pci_map_single interface. Here the scatter gather list
95 * elements are each tagged with the appropriate dma address
96 * and length. They are obtained via sg_dma_{address,length}(SG).
97 *
98 * NOTE: An implementation may be able to use a smaller number of
99 * DMA address/length pairs than there are SG table elements.
100 * (for example via virtual mapping capabilities)
101 * The routine returns the number of addr/length pairs actually
102 * used, at most nents.
103 *
104 * Device ownership issues as mentioned above for pci_map_single are
105 * the same here.
106 */
107extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
108
109/* Unmap a set of streaming mode DMA translations.
110 * Again, cpu read rules concerning calls here are the same as for
111 * pci_unmap_single() above.
112 */
113extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction);
114
115/* Make physical memory consistent for a single
116 * streaming mode DMA translation after a transfer.
117 *
118 * If you perform a pci_map_single() but wish to interrogate the
119 * buffer using the cpu, yet do not wish to teardown the PCI dma
120 * mapping, you must call this function before doing so. At the
121 * next point you give the PCI dma address back to the card, you
122 * must first perform a pci_dma_sync_for_device, and then the device
123 * again owns the buffer.
124 */
125extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
126extern void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
127
128/* Make physical memory consistent for a set of streaming
129 * mode DMA translations after a transfer.
130 *
131 * The same as pci_dma_sync_single_* but for a scatter-gather list,
132 * same rules and usage.
133 */
134extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
135extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
136
137/* Return whether the given PCI device DMA address mask can
138 * be supported properly. For example, if your device can
139 * only drive the low 24-bits during PCI bus mastering, then
140 * you would pass 0x00ffffff as the mask to this function.
141 */
142static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
143{
144 return 1;
145}
146
147#ifdef CONFIG_PCI 50#ifdef CONFIG_PCI
148static inline void pci_dma_burst_advice(struct pci_dev *pdev, 51static inline void pci_dma_burst_advice(struct pci_dev *pdev,
149 enum pci_dma_burst_strategy *strat, 52 enum pci_dma_burst_strategy *strat,
@@ -154,14 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
154} 57}
155#endif 58#endif
156 59
157#define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0)
158
159static inline int pci_dma_mapping_error(struct pci_dev *pdev,
160 dma_addr_t dma_addr)
161{
162 return (dma_addr == PCI_DMA_ERROR_CODE);
163}
164
165struct device_node; 60struct device_node;
166extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev); 61extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
167 62
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 7a1e3566e59c..5cc9f6aa5494 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -35,37 +35,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
35 */ 35 */
36#define PCI_DMA_BUS_IS_PHYS (0) 36#define PCI_DMA_BUS_IS_PHYS (0)
37 37
38static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size,
39 dma_addr_t *dma_handle)
40{
41 return dma_alloc_coherent(&pdev->dev, size, dma_handle, GFP_ATOMIC);
42}
43
44static inline void pci_free_consistent(struct pci_dev *pdev, size_t size,
45 void *vaddr, dma_addr_t dma_handle)
46{
47 return dma_free_coherent(&pdev->dev, size, vaddr, dma_handle);
48}
49
50static inline dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr,
51 size_t size, int direction)
52{
53 return dma_map_single(&pdev->dev, ptr, size,
54 (enum dma_data_direction) direction);
55}
56
57static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr,
58 size_t size, int direction)
59{
60 dma_unmap_single(&pdev->dev, dma_addr, size,
61 (enum dma_data_direction) direction);
62}
63
64#define pci_map_page(dev, page, off, size, dir) \
65 pci_map_single(dev, (page_address(page) + (off)), size, dir)
66#define pci_unmap_page(dev,addr,sz,dir) \
67 pci_unmap_single(dev,addr,sz,dir)
68
69/* pci_unmap_{single,page} is not a nop, thus... */ 38/* pci_unmap_{single,page} is not a nop, thus... */
70#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ 39#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
71 dma_addr_t ADDR_NAME; 40 dma_addr_t ADDR_NAME;
@@ -80,57 +49,6 @@ static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr,
80#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ 49#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
81 (((PTR)->LEN_NAME) = (VAL)) 50 (((PTR)->LEN_NAME) = (VAL))
82 51
83static inline int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg,
84 int nents, int direction)
85{
86 return dma_map_sg(&pdev->dev, sg, nents,
87 (enum dma_data_direction) direction);
88}
89
90static inline void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg,
91 int nents, int direction)
92{
93 dma_unmap_sg(&pdev->dev, sg, nents,
94 (enum dma_data_direction) direction);
95}
96
97static inline void pci_dma_sync_single_for_cpu(struct pci_dev *pdev,
98 dma_addr_t dma_handle,
99 size_t size, int direction)
100{
101 dma_sync_single_for_cpu(&pdev->dev, dma_handle, size,
102 (enum dma_data_direction) direction);
103}
104
105static inline void pci_dma_sync_single_for_device(struct pci_dev *pdev,
106 dma_addr_t dma_handle,
107 size_t size, int direction)
108{
109 /* No flushing needed to sync cpu writes to the device. */
110}
111
112static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev,
113 struct scatterlist *sg,
114 int nents, int direction)
115{
116 dma_sync_sg_for_cpu(&pdev->dev, sg, nents,
117 (enum dma_data_direction) direction);
118}
119
120static inline void pci_dma_sync_sg_for_device(struct pci_dev *pdev,
121 struct scatterlist *sg,
122 int nelems, int direction)
123{
124 /* No flushing needed to sync cpu writes to the device. */
125}
126
127/* Return whether the given PCI device DMA address mask can
128 * be supported properly. For example, if your device can
129 * only drive the low 24-bits during PCI bus mastering, then
130 * you would pass 0x00ffffff as the mask to this function.
131 */
132extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
133
134/* PCI IOMMU mapping bypass support. */ 52/* PCI IOMMU mapping bypass support. */
135 53
136/* PCI 64-bit addressing works for all slots on all controller 54/* PCI 64-bit addressing works for all slots on all controller
@@ -140,12 +58,6 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
140#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) 58#define PCI64_REQUIRED_MASK (~(dma64_addr_t)0)
141#define PCI64_ADDR_BASE 0xfffc000000000000UL 59#define PCI64_ADDR_BASE 0xfffc000000000000UL
142 60
143static inline int pci_dma_mapping_error(struct pci_dev *pdev,
144 dma_addr_t dma_addr)
145{
146 return dma_mapping_error(&pdev->dev, dma_addr);
147}
148
149#ifdef CONFIG_PCI 61#ifdef CONFIG_PCI
150static inline void pci_dma_burst_advice(struct pci_dev *pdev, 62static inline void pci_dma_burst_advice(struct pci_dev *pdev,
151 enum pci_dma_burst_strategy *strat, 63 enum pci_dma_burst_strategy *strat,
diff --git a/arch/sparc/include/asm/perf_counter.h b/arch/sparc/include/asm/perf_counter.h
new file mode 100644
index 000000000000..5d7a8ca0e491
--- /dev/null
+++ b/arch/sparc/include/asm/perf_counter.h
@@ -0,0 +1,14 @@
1#ifndef __ASM_SPARC_PERF_COUNTER_H
2#define __ASM_SPARC_PERF_COUNTER_H
3
4extern void set_perf_counter_pending(void);
5
6#define PERF_COUNTER_INDEX_OFFSET 0
7
8#ifdef CONFIG_PERF_COUNTERS
9extern void init_hw_perf_counters(void);
10#else
11static inline void init_hw_perf_counters(void) { }
12#endif
13
14#endif
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h
index 808555fc1d58..1407c07bdade 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -267,6 +267,7 @@ static inline void srmmu_flush_tlb_page(unsigned long page)
267 267
268} 268}
269 269
270#ifndef CONFIG_SPARC_LEON
270static inline unsigned long srmmu_hwprobe(unsigned long vaddr) 271static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
271{ 272{
272 unsigned long retval; 273 unsigned long retval;
@@ -278,6 +279,9 @@ static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
278 279
279 return retval; 280 return retval;
280} 281}
282#else
283#define srmmu_hwprobe(addr) (srmmu_swprobe(addr, 0) & SRMMU_PTE_PMASK)
284#endif
281 285
282static inline int 286static inline int
283srmmu_get_pte (unsigned long addr) 287srmmu_get_pte (unsigned long addr)
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index be8d7aaeb60d..82a190d7efc1 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -118,5 +118,8 @@ extern struct device_node *of_console_device;
118extern char *of_console_path; 118extern char *of_console_path;
119extern char *of_console_options; 119extern char *of_console_options;
120 120
121extern void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
122extern char *build_full_name(struct device_node *dp);
123
121#endif /* __KERNEL__ */ 124#endif /* __KERNEL__ */
122#endif /* _SPARC_PROM_H */ 125#endif /* _SPARC_PROM_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 982a12f959f4..3a5ae3d12088 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -29,6 +29,9 @@
29#define SO_RCVBUFFORCE 0x100b 29#define SO_RCVBUFFORCE 0x100b
30#define SO_ERROR 0x1007 30#define SO_ERROR 0x1007
31#define SO_TYPE 0x1008 31#define SO_TYPE 0x1008
32#define SO_PROTOCOL 0x1028
33#define SO_DOMAIN 0x1029
34
32 35
33/* Linux specific, keep the same. */ 36/* Linux specific, keep the same. */
34#define SO_NO_CHECK 0x000b 37#define SO_NO_CHECK 0x000b
diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h
index 46f91ab66a50..857630cff636 100644
--- a/arch/sparc/include/asm/spinlock_32.h
+++ b/arch/sparc/include/asm/spinlock_32.h
@@ -76,7 +76,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
76 * 76 *
77 * Unfortunately this scheme limits us to ~16,000,000 cpus. 77 * Unfortunately this scheme limits us to ~16,000,000 cpus.
78 */ 78 */
79static inline void __read_lock(raw_rwlock_t *rw) 79static inline void arch_read_lock(raw_rwlock_t *rw)
80{ 80{
81 register raw_rwlock_t *lp asm("g1"); 81 register raw_rwlock_t *lp asm("g1");
82 lp = rw; 82 lp = rw;
@@ -92,11 +92,11 @@ static inline void __read_lock(raw_rwlock_t *rw)
92#define __raw_read_lock(lock) \ 92#define __raw_read_lock(lock) \
93do { unsigned long flags; \ 93do { unsigned long flags; \
94 local_irq_save(flags); \ 94 local_irq_save(flags); \
95 __read_lock(lock); \ 95 arch_read_lock(lock); \
96 local_irq_restore(flags); \ 96 local_irq_restore(flags); \
97} while(0) 97} while(0)
98 98
99static inline void __read_unlock(raw_rwlock_t *rw) 99static inline void arch_read_unlock(raw_rwlock_t *rw)
100{ 100{
101 register raw_rwlock_t *lp asm("g1"); 101 register raw_rwlock_t *lp asm("g1");
102 lp = rw; 102 lp = rw;
@@ -112,7 +112,7 @@ static inline void __read_unlock(raw_rwlock_t *rw)
112#define __raw_read_unlock(lock) \ 112#define __raw_read_unlock(lock) \
113do { unsigned long flags; \ 113do { unsigned long flags; \
114 local_irq_save(flags); \ 114 local_irq_save(flags); \
115 __read_unlock(lock); \ 115 arch_read_unlock(lock); \
116 local_irq_restore(flags); \ 116 local_irq_restore(flags); \
117} while(0) 117} while(0)
118 118
@@ -150,7 +150,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
150 return (val == 0); 150 return (val == 0);
151} 151}
152 152
153static inline int __read_trylock(raw_rwlock_t *rw) 153static inline int arch_read_trylock(raw_rwlock_t *rw)
154{ 154{
155 register raw_rwlock_t *lp asm("g1"); 155 register raw_rwlock_t *lp asm("g1");
156 register int res asm("o0"); 156 register int res asm("o0");
@@ -169,7 +169,7 @@ static inline int __read_trylock(raw_rwlock_t *rw)
169({ unsigned long flags; \ 169({ unsigned long flags; \
170 int res; \ 170 int res; \
171 local_irq_save(flags); \ 171 local_irq_save(flags); \
172 res = __read_trylock(lock); \ 172 res = arch_read_trylock(lock); \
173 local_irq_restore(flags); \ 173 local_irq_restore(flags); \
174 res; \ 174 res; \
175}) 175})
diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h
index f6b2b92ad8d2..43e514783582 100644
--- a/arch/sparc/include/asm/spinlock_64.h
+++ b/arch/sparc/include/asm/spinlock_64.h
@@ -92,7 +92,7 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla
92 92
93/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ 93/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
94 94
95static void inline __read_lock(raw_rwlock_t *lock) 95static void inline arch_read_lock(raw_rwlock_t *lock)
96{ 96{
97 unsigned long tmp1, tmp2; 97 unsigned long tmp1, tmp2;
98 98
@@ -115,7 +115,7 @@ static void inline __read_lock(raw_rwlock_t *lock)
115 : "memory"); 115 : "memory");
116} 116}
117 117
118static int inline __read_trylock(raw_rwlock_t *lock) 118static int inline arch_read_trylock(raw_rwlock_t *lock)
119{ 119{
120 int tmp1, tmp2; 120 int tmp1, tmp2;
121 121
@@ -136,7 +136,7 @@ static int inline __read_trylock(raw_rwlock_t *lock)
136 return tmp1; 136 return tmp1;
137} 137}
138 138
139static void inline __read_unlock(raw_rwlock_t *lock) 139static void inline arch_read_unlock(raw_rwlock_t *lock)
140{ 140{
141 unsigned long tmp1, tmp2; 141 unsigned long tmp1, tmp2;
142 142
@@ -152,7 +152,7 @@ static void inline __read_unlock(raw_rwlock_t *lock)
152 : "memory"); 152 : "memory");
153} 153}
154 154
155static void inline __write_lock(raw_rwlock_t *lock) 155static void inline arch_write_lock(raw_rwlock_t *lock)
156{ 156{
157 unsigned long mask, tmp1, tmp2; 157 unsigned long mask, tmp1, tmp2;
158 158
@@ -177,7 +177,7 @@ static void inline __write_lock(raw_rwlock_t *lock)
177 : "memory"); 177 : "memory");
178} 178}
179 179
180static void inline __write_unlock(raw_rwlock_t *lock) 180static void inline arch_write_unlock(raw_rwlock_t *lock)
181{ 181{
182 __asm__ __volatile__( 182 __asm__ __volatile__(
183" stw %%g0, [%0]" 183" stw %%g0, [%0]"
@@ -186,7 +186,7 @@ static void inline __write_unlock(raw_rwlock_t *lock)
186 : "memory"); 186 : "memory");
187} 187}
188 188
189static int inline __write_trylock(raw_rwlock_t *lock) 189static int inline arch_write_trylock(raw_rwlock_t *lock)
190{ 190{
191 unsigned long mask, tmp1, tmp2, result; 191 unsigned long mask, tmp1, tmp2, result;
192 192
@@ -210,14 +210,14 @@ static int inline __write_trylock(raw_rwlock_t *lock)
210 return result; 210 return result;
211} 211}
212 212
213#define __raw_read_lock(p) __read_lock(p) 213#define __raw_read_lock(p) arch_read_lock(p)
214#define __raw_read_lock_flags(p, f) __read_lock(p) 214#define __raw_read_lock_flags(p, f) arch_read_lock(p)
215#define __raw_read_trylock(p) __read_trylock(p) 215#define __raw_read_trylock(p) arch_read_trylock(p)
216#define __raw_read_unlock(p) __read_unlock(p) 216#define __raw_read_unlock(p) arch_read_unlock(p)
217#define __raw_write_lock(p) __write_lock(p) 217#define __raw_write_lock(p) arch_write_lock(p)
218#define __raw_write_lock_flags(p, f) __write_lock(p) 218#define __raw_write_lock_flags(p, f) arch_write_lock(p)
219#define __raw_write_unlock(p) __write_unlock(p) 219#define __raw_write_unlock(p) arch_write_unlock(p)
220#define __raw_write_trylock(p) __write_trylock(p) 220#define __raw_write_trylock(p) arch_write_trylock(p)
221 221
222#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) 222#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))
223#define __raw_write_can_lock(rw) (!(rw)->lock) 223#define __raw_write_can_lock(rw) (!(rw)->lock)
diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h
index 751c8c17f5a0..890036b3689a 100644
--- a/arch/sparc/include/asm/system_32.h
+++ b/arch/sparc/include/asm/system_32.h
@@ -32,6 +32,7 @@ enum sparc_cpu {
32 sun4u = 0x05, /* V8 ploos ploos */ 32 sun4u = 0x05, /* V8 ploos ploos */
33 sun_unknown = 0x06, 33 sun_unknown = 0x06,
34 ap1000 = 0x07, /* almost a sun4m */ 34 ap1000 = 0x07, /* almost a sun4m */
35 sparc_leon = 0x08, /* Leon SoC */
35}; 36};
36 37
37/* Really, userland should not be looking at any of this... */ 38/* Really, userland should not be looking at any of this... */
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h
index 6c077816ab28..25e848f0cad7 100644
--- a/arch/sparc/include/asm/system_64.h
+++ b/arch/sparc/include/asm/system_64.h
@@ -29,6 +29,10 @@ enum sparc_cpu {
29/* This cannot ever be a sun4c :) That's just history. */ 29/* This cannot ever be a sun4c :) That's just history. */
30#define ARCH_SUN4C 0 30#define ARCH_SUN4C 0
31 31
32extern const char *sparc_cpu_type;
33extern const char *sparc_fpu_type;
34extern const char *sparc_pmu_type;
35
32extern char reboot_command[]; 36extern char reboot_command[];
33 37
34/* These are here in an effort to more fully work around Spitfire Errata 38/* These are here in an effort to more fully work around Spitfire Errata
diff --git a/arch/sparc/include/asm/types.h b/arch/sparc/include/asm/types.h
index de671d73baed..09c79a9c8516 100644
--- a/arch/sparc/include/asm/types.h
+++ b/arch/sparc/include/asm/types.h
@@ -8,9 +8,8 @@
8 * need to be careful to avoid a name clashes. 8 * need to be careful to avoid a name clashes.
9 */ 9 */
10 10
11#if defined(__sparc__) && defined(__arch64__) 11#if defined(__sparc__)
12 12
13/*** SPARC 64 bit ***/
14#include <asm-generic/int-ll64.h> 13#include <asm-generic/int-ll64.h>
15 14
16#ifndef __ASSEMBLY__ 15#ifndef __ASSEMBLY__
@@ -26,33 +25,21 @@ typedef unsigned short umode_t;
26/* Dma addresses come in generic and 64-bit flavours. */ 25/* Dma addresses come in generic and 64-bit flavours. */
27 26
28typedef u32 dma_addr_t; 27typedef u32 dma_addr_t;
29typedef u64 dma64_addr_t;
30 28
31#endif /* __ASSEMBLY__ */ 29#if defined(__arch64__)
32 30
33#endif /* __KERNEL__ */ 31/*** SPARC 64 bit ***/
32typedef u64 dma64_addr_t;
34#else 33#else
35
36/*** SPARC 32 bit ***/ 34/*** SPARC 32 bit ***/
37#include <asm-generic/int-ll64.h>
38
39#ifndef __ASSEMBLY__
40
41typedef unsigned short umode_t;
42
43#endif /* __ASSEMBLY__ */
44
45#ifdef __KERNEL__
46
47#ifndef __ASSEMBLY__
48
49typedef u32 dma_addr_t;
50typedef u32 dma64_addr_t; 35typedef u32 dma64_addr_t;
51 36
37#endif /* defined(__arch64__) */
38
52#endif /* __ASSEMBLY__ */ 39#endif /* __ASSEMBLY__ */
53 40
54#endif /* __KERNEL__ */ 41#endif /* __KERNEL__ */
55 42
56#endif /* defined(__sparc__) && defined(__arch64__) */ 43#endif /* defined(__sparc__) */
57 44
58#endif /* defined(_SPARC_TYPES_H) */ 45#endif /* defined(_SPARC_TYPES_H) */
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index a38c03238918..9ea271e19c70 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -7,8 +7,8 @@
7 7
8#ifdef __KERNEL__ 8#ifdef __KERNEL__
9#include <linux/compiler.h> 9#include <linux/compiler.h>
10#include <linux/sched.h>
11#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/thread_info.h>
12#include <asm/asi.h> 12#include <asm/asi.h>
13#include <asm/system.h> 13#include <asm/system.h>
14#include <asm/spitfire.h> 14#include <asm/spitfire.h>
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index b2c406de7d4f..706df669f3b8 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -395,8 +395,9 @@
395#define __NR_preadv 324 395#define __NR_preadv 324
396#define __NR_pwritev 325 396#define __NR_pwritev 325
397#define __NR_rt_tgsigqueueinfo 326 397#define __NR_rt_tgsigqueueinfo 326
398#define __NR_perf_counter_open 327
398 399
399#define NR_SYSCALLS 327 400#define NR_SYSCALLS 328
400 401
401#ifdef __32bit_syscall_numbers__ 402#ifdef __32bit_syscall_numbers__
402/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, 403/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 475ce4696acd..247cc620cee5 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -41,6 +41,8 @@ obj-y += of_device_common.o
41obj-y += of_device_$(BITS).o 41obj-y += of_device_$(BITS).o
42obj-$(CONFIG_SPARC64) += prom_irqtrans.o 42obj-$(CONFIG_SPARC64) += prom_irqtrans.o
43 43
44obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o
45
44obj-$(CONFIG_SPARC64) += reboot.o 46obj-$(CONFIG_SPARC64) += reboot.o
45obj-$(CONFIG_SPARC64) += sysfs.o 47obj-$(CONFIG_SPARC64) += sysfs.o
46obj-$(CONFIG_SPARC64) += iommu.o 48obj-$(CONFIG_SPARC64) += iommu.o
@@ -61,7 +63,7 @@ obj-$(CONFIG_SPARC64_SMP) += cpumap.o
61obj-$(CONFIG_SPARC32) += devres.o 63obj-$(CONFIG_SPARC32) += devres.o
62devres-y := ../../../kernel/irq/devres.o 64devres-y := ../../../kernel/irq/devres.o
63 65
64obj-$(CONFIG_SPARC32) += dma.o 66obj-y += dma.o
65 67
66obj-$(CONFIG_SPARC32_PCI) += pcic.o 68obj-$(CONFIG_SPARC32_PCI) += pcic.o
67 69
@@ -101,3 +103,6 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
101obj-$(CONFIG_AUDIT) += audit.o 103obj-$(CONFIG_AUDIT) += audit.o
102audit--$(CONFIG_AUDIT) := compat_audit.o 104audit--$(CONFIG_AUDIT) := compat_audit.o
103obj-$(CONFIG_COMPAT) += $(audit--y) 105obj-$(CONFIG_COMPAT) += $(audit--y)
106
107pc--$(CONFIG_PERF_COUNTERS) := perf_counter.o
108obj-$(CONFIG_SPARC64) += $(pc--y)
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index d85c3dc4953a..1446df90ef85 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -312,7 +312,12 @@ void __cpuinit cpu_probe(void)
312 312
313 psr = get_psr(); 313 psr = get_psr();
314 put_psr(psr | PSR_EF); 314 put_psr(psr | PSR_EF);
315#ifdef CONFIG_SPARC_LEON
316 fpu_vers = 7;
317#else
315 fpu_vers = ((get_fsr() >> 17) & 0x7); 318 fpu_vers = ((get_fsr() >> 17) & 0x7);
319#endif
320
316 put_psr(psr); 321 put_psr(psr);
317 322
318 set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers); 323 set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers);
diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c
index 524c32f97c55..e1ba8ee21b9a 100644
--- a/arch/sparc/kernel/dma.c
+++ b/arch/sparc/kernel/dma.c
@@ -1,178 +1,13 @@
1/* dma.c: PCI and SBUS DMA accessors for 32-bit sparc.
2 *
3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
4 */
5
6#include <linux/kernel.h> 1#include <linux/kernel.h>
7#include <linux/module.h> 2#include <linux/module.h>
8#include <linux/dma-mapping.h> 3#include <linux/dma-mapping.h>
9#include <linux/scatterlist.h> 4#include <linux/dma-debug.h>
10#include <linux/mm.h>
11
12#ifdef CONFIG_PCI
13#include <linux/pci.h>
14#endif
15 5
16#include "dma.h" 6#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 15)
17 7
18int dma_supported(struct device *dev, u64 mask) 8static int __init dma_init(void)
19{ 9{
20#ifdef CONFIG_PCI 10 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
21 if (dev->bus == &pci_bus_type)
22 return pci_dma_supported(to_pci_dev(dev), mask);
23#endif
24 return 0; 11 return 0;
25} 12}
26EXPORT_SYMBOL(dma_supported); 13fs_initcall(dma_init);
27
28int dma_set_mask(struct device *dev, u64 dma_mask)
29{
30#ifdef CONFIG_PCI
31 if (dev->bus == &pci_bus_type)
32 return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
33#endif
34 return -EOPNOTSUPP;
35}
36EXPORT_SYMBOL(dma_set_mask);
37
38static void *dma32_alloc_coherent(struct device *dev, size_t size,
39 dma_addr_t *dma_handle, gfp_t flag)
40{
41#ifdef CONFIG_PCI
42 if (dev->bus == &pci_bus_type)
43 return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
44#endif
45 return sbus_alloc_consistent(dev, size, dma_handle);
46}
47
48static void dma32_free_coherent(struct device *dev, size_t size,
49 void *cpu_addr, dma_addr_t dma_handle)
50{
51#ifdef CONFIG_PCI
52 if (dev->bus == &pci_bus_type) {
53 pci_free_consistent(to_pci_dev(dev), size,
54 cpu_addr, dma_handle);
55 return;
56 }
57#endif
58 sbus_free_consistent(dev, size, cpu_addr, dma_handle);
59}
60
61static dma_addr_t dma32_map_page(struct device *dev, struct page *page,
62 unsigned long offset, size_t size,
63 enum dma_data_direction direction)
64{
65#ifdef CONFIG_PCI
66 if (dev->bus == &pci_bus_type)
67 return pci_map_page(to_pci_dev(dev), page, offset,
68 size, (int)direction);
69#endif
70 return sbus_map_single(dev, page_address(page) + offset,
71 size, (int)direction);
72}
73
74static void dma32_unmap_page(struct device *dev, dma_addr_t dma_address,
75 size_t size, enum dma_data_direction direction)
76{
77#ifdef CONFIG_PCI
78 if (dev->bus == &pci_bus_type) {
79 pci_unmap_page(to_pci_dev(dev), dma_address,
80 size, (int)direction);
81 return;
82 }
83#endif
84 sbus_unmap_single(dev, dma_address, size, (int)direction);
85}
86
87static int dma32_map_sg(struct device *dev, struct scatterlist *sg,
88 int nents, enum dma_data_direction direction)
89{
90#ifdef CONFIG_PCI
91 if (dev->bus == &pci_bus_type)
92 return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
93#endif
94 return sbus_map_sg(dev, sg, nents, direction);
95}
96
97void dma32_unmap_sg(struct device *dev, struct scatterlist *sg,
98 int nents, enum dma_data_direction direction)
99{
100#ifdef CONFIG_PCI
101 if (dev->bus == &pci_bus_type) {
102 pci_unmap_sg(to_pci_dev(dev), sg, nents, (int)direction);
103 return;
104 }
105#endif
106 sbus_unmap_sg(dev, sg, nents, (int)direction);
107}
108
109static void dma32_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
110 size_t size,
111 enum dma_data_direction direction)
112{
113#ifdef CONFIG_PCI
114 if (dev->bus == &pci_bus_type) {
115 pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle,
116 size, (int)direction);
117 return;
118 }
119#endif
120 sbus_dma_sync_single_for_cpu(dev, dma_handle, size, (int) direction);
121}
122
123static void dma32_sync_single_for_device(struct device *dev,
124 dma_addr_t dma_handle, size_t size,
125 enum dma_data_direction direction)
126{
127#ifdef CONFIG_PCI
128 if (dev->bus == &pci_bus_type) {
129 pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle,
130 size, (int)direction);
131 return;
132 }
133#endif
134 sbus_dma_sync_single_for_device(dev, dma_handle, size, (int) direction);
135}
136
137static void dma32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
138 int nelems, enum dma_data_direction direction)
139{
140#ifdef CONFIG_PCI
141 if (dev->bus == &pci_bus_type) {
142 pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg,
143 nelems, (int)direction);
144 return;
145 }
146#endif
147 BUG();
148}
149
150static void dma32_sync_sg_for_device(struct device *dev,
151 struct scatterlist *sg, int nelems,
152 enum dma_data_direction direction)
153{
154#ifdef CONFIG_PCI
155 if (dev->bus == &pci_bus_type) {
156 pci_dma_sync_sg_for_device(to_pci_dev(dev), sg,
157 nelems, (int)direction);
158 return;
159 }
160#endif
161 BUG();
162}
163
164static const struct dma_ops dma32_dma_ops = {
165 .alloc_coherent = dma32_alloc_coherent,
166 .free_coherent = dma32_free_coherent,
167 .map_page = dma32_map_page,
168 .unmap_page = dma32_unmap_page,
169 .map_sg = dma32_map_sg,
170 .unmap_sg = dma32_unmap_sg,
171 .sync_single_for_cpu = dma32_sync_single_for_cpu,
172 .sync_single_for_device = dma32_sync_single_for_device,
173 .sync_sg_for_cpu = dma32_sync_sg_for_cpu,
174 .sync_sg_for_device = dma32_sync_sg_for_device,
175};
176
177const struct dma_ops *dma_ops = &dma32_dma_ops;
178EXPORT_SYMBOL(dma_ops);
diff --git a/arch/sparc/kernel/dma.h b/arch/sparc/kernel/dma.h
deleted file mode 100644
index f8d8951adb53..000000000000
--- a/arch/sparc/kernel/dma.h
+++ /dev/null
@@ -1,14 +0,0 @@
1void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp);
2void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba);
3dma_addr_t sbus_map_single(struct device *dev, void *va,
4 size_t len, int direction);
5void sbus_unmap_single(struct device *dev, dma_addr_t ba,
6 size_t n, int direction);
7int sbus_map_sg(struct device *dev, struct scatterlist *sg,
8 int n, int direction);
9void sbus_unmap_sg(struct device *dev, struct scatterlist *sg,
10 int n, int direction);
11void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba,
12 size_t size, int direction);
13void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba,
14 size_t size, int direction);
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 6b4d8acc4c83..439d82a95ac9 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -809,6 +809,11 @@ found_version:
809 nop 809 nop
810 810
811got_prop: 811got_prop:
812#ifdef CONFIG_SPARC_LEON
813 /* no cpu-type check is needed, it is a SPARC-LEON */
814 ba sun4c_continue_boot
815 nop
816#endif
812 set cputypval, %o2 817 set cputypval, %o2
813 ldub [%o2 + 0x4], %l1 818 ldub [%o2 + 0x4], %l1
814 819
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
index 57922f69c3f7..52a15fe2db19 100644
--- a/arch/sparc/kernel/idprom.c
+++ b/arch/sparc/kernel/idprom.c
@@ -31,6 +31,8 @@ static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
31{ .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) }, 31{ .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) },
32{ .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) }, 32{ .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) },
33{ .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) }, 33{ .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) },
34/* Now Leon */
35{ .name = "Leon3 System-on-a-Chip", .id_machtype = (M_LEON | M_LEON3_SOC) },
34/* Now, Sun4c's */ 36/* Now, Sun4c's */
35{ .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) }, 37{ .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) },
36{ .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) }, 38{ .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) },
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 0aeaefe696b9..7690cc219ecc 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -353,7 +353,8 @@ static void dma_4u_free_coherent(struct device *dev, size_t size,
353 353
354static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, 354static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page,
355 unsigned long offset, size_t sz, 355 unsigned long offset, size_t sz,
356 enum dma_data_direction direction) 356 enum dma_data_direction direction,
357 struct dma_attrs *attrs)
357{ 358{
358 struct iommu *iommu; 359 struct iommu *iommu;
359 struct strbuf *strbuf; 360 struct strbuf *strbuf;
@@ -474,7 +475,8 @@ do_flush_sync:
474} 475}
475 476
476static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, 477static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr,
477 size_t sz, enum dma_data_direction direction) 478 size_t sz, enum dma_data_direction direction,
479 struct dma_attrs *attrs)
478{ 480{
479 struct iommu *iommu; 481 struct iommu *iommu;
480 struct strbuf *strbuf; 482 struct strbuf *strbuf;
@@ -520,7 +522,8 @@ static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr,
520} 522}
521 523
522static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, 524static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
523 int nelems, enum dma_data_direction direction) 525 int nelems, enum dma_data_direction direction,
526 struct dma_attrs *attrs)
524{ 527{
525 struct scatterlist *s, *outs, *segstart; 528 struct scatterlist *s, *outs, *segstart;
526 unsigned long flags, handle, prot, ctx; 529 unsigned long flags, handle, prot, ctx;
@@ -691,7 +694,8 @@ static unsigned long fetch_sg_ctx(struct iommu *iommu, struct scatterlist *sg)
691} 694}
692 695
693static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, 696static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
694 int nelems, enum dma_data_direction direction) 697 int nelems, enum dma_data_direction direction,
698 struct dma_attrs *attrs)
695{ 699{
696 unsigned long flags, ctx; 700 unsigned long flags, ctx;
697 struct scatterlist *sg; 701 struct scatterlist *sg;
@@ -822,7 +826,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
822 spin_unlock_irqrestore(&iommu->lock, flags); 826 spin_unlock_irqrestore(&iommu->lock, flags);
823} 827}
824 828
825static const struct dma_ops sun4u_dma_ops = { 829static struct dma_map_ops sun4u_dma_ops = {
826 .alloc_coherent = dma_4u_alloc_coherent, 830 .alloc_coherent = dma_4u_alloc_coherent,
827 .free_coherent = dma_4u_free_coherent, 831 .free_coherent = dma_4u_free_coherent,
828 .map_page = dma_4u_map_page, 832 .map_page = dma_4u_map_page,
@@ -833,9 +837,11 @@ static const struct dma_ops sun4u_dma_ops = {
833 .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu, 837 .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu,
834}; 838};
835 839
836const struct dma_ops *dma_ops = &sun4u_dma_ops; 840struct dma_map_ops *dma_ops = &sun4u_dma_ops;
837EXPORT_SYMBOL(dma_ops); 841EXPORT_SYMBOL(dma_ops);
838 842
843extern int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask);
844
839int dma_supported(struct device *dev, u64 device_mask) 845int dma_supported(struct device *dev, u64 device_mask)
840{ 846{
841 struct iommu *iommu = dev->archdata.iommu; 847 struct iommu *iommu = dev->archdata.iommu;
@@ -849,7 +855,7 @@ int dma_supported(struct device *dev, u64 device_mask)
849 855
850#ifdef CONFIG_PCI 856#ifdef CONFIG_PCI
851 if (dev->bus == &pci_bus_type) 857 if (dev->bus == &pci_bus_type)
852 return pci_dma_supported(to_pci_dev(dev), device_mask); 858 return pci64_dma_supported(to_pci_dev(dev), device_mask);
853#endif 859#endif
854 860
855 return 0; 861 return 0;
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 87ea0d03d975..9f61fd8cbb7b 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -35,6 +35,7 @@
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/pci.h> /* struct pci_dev */ 36#include <linux/pci.h> /* struct pci_dev */
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/seq_file.h>
38#include <linux/scatterlist.h> 39#include <linux/scatterlist.h>
39#include <linux/of_device.h> 40#include <linux/of_device.h>
40 41
@@ -48,8 +49,6 @@
48#include <asm/iommu.h> 49#include <asm/iommu.h>
49#include <asm/io-unit.h> 50#include <asm/io-unit.h>
50 51
51#include "dma.h"
52
53#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ 52#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */
54 53
55static struct resource *_sparc_find_resource(struct resource *r, 54static struct resource *_sparc_find_resource(struct resource *r,
@@ -246,7 +245,8 @@ EXPORT_SYMBOL(sbus_set_sbus64);
246 * Typically devices use them for control blocks. 245 * Typically devices use them for control blocks.
247 * CPU may access them without any explicit flushing. 246 * CPU may access them without any explicit flushing.
248 */ 247 */
249void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp) 248static void *sbus_alloc_coherent(struct device *dev, size_t len,
249 dma_addr_t *dma_addrp, gfp_t gfp)
250{ 250{
251 struct of_device *op = to_of_device(dev); 251 struct of_device *op = to_of_device(dev);
252 unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; 252 unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
@@ -299,7 +299,8 @@ err_nopages:
299 return NULL; 299 return NULL;
300} 300}
301 301
302void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba) 302static void sbus_free_coherent(struct device *dev, size_t n, void *p,
303 dma_addr_t ba)
303{ 304{
304 struct resource *res; 305 struct resource *res;
305 struct page *pgv; 306 struct page *pgv;
@@ -317,7 +318,7 @@ void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba)
317 318
318 n = (n + PAGE_SIZE-1) & PAGE_MASK; 319 n = (n + PAGE_SIZE-1) & PAGE_MASK;
319 if ((res->end-res->start)+1 != n) { 320 if ((res->end-res->start)+1 != n) {
320 printk("sbus_free_consistent: region 0x%lx asked 0x%lx\n", 321 printk("sbus_free_consistent: region 0x%lx asked 0x%zx\n",
321 (long)((res->end-res->start)+1), n); 322 (long)((res->end-res->start)+1), n);
322 return; 323 return;
323 } 324 }
@@ -337,8 +338,13 @@ void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba)
337 * CPU view of this memory may be inconsistent with 338 * CPU view of this memory may be inconsistent with
338 * a device view and explicit flushing is necessary. 339 * a device view and explicit flushing is necessary.
339 */ 340 */
340dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int direction) 341static dma_addr_t sbus_map_page(struct device *dev, struct page *page,
342 unsigned long offset, size_t len,
343 enum dma_data_direction dir,
344 struct dma_attrs *attrs)
341{ 345{
346 void *va = page_address(page) + offset;
347
342 /* XXX why are some lengths signed, others unsigned? */ 348 /* XXX why are some lengths signed, others unsigned? */
343 if (len <= 0) { 349 if (len <= 0) {
344 return 0; 350 return 0;
@@ -350,12 +356,14 @@ dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int directi
350 return mmu_get_scsi_one(dev, va, len); 356 return mmu_get_scsi_one(dev, va, len);
351} 357}
352 358
353void sbus_unmap_single(struct device *dev, dma_addr_t ba, size_t n, int direction) 359static void sbus_unmap_page(struct device *dev, dma_addr_t ba, size_t n,
360 enum dma_data_direction dir, struct dma_attrs *attrs)
354{ 361{
355 mmu_release_scsi_one(dev, ba, n); 362 mmu_release_scsi_one(dev, ba, n);
356} 363}
357 364
358int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction) 365static int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n,
366 enum dma_data_direction dir, struct dma_attrs *attrs)
359{ 367{
360 mmu_get_scsi_sgl(dev, sg, n); 368 mmu_get_scsi_sgl(dev, sg, n);
361 369
@@ -366,19 +374,38 @@ int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction
366 return n; 374 return n;
367} 375}
368 376
369void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n, int direction) 377static void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n,
378 enum dma_data_direction dir, struct dma_attrs *attrs)
370{ 379{
371 mmu_release_scsi_sgl(dev, sg, n); 380 mmu_release_scsi_sgl(dev, sg, n);
372} 381}
373 382
374void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, int direction) 383static void sbus_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
384 int n, enum dma_data_direction dir)
375{ 385{
386 BUG();
376} 387}
377 388
378void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, int direction) 389static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
390 int n, enum dma_data_direction dir)
379{ 391{
392 BUG();
380} 393}
381 394
395struct dma_map_ops sbus_dma_ops = {
396 .alloc_coherent = sbus_alloc_coherent,
397 .free_coherent = sbus_free_coherent,
398 .map_page = sbus_map_page,
399 .unmap_page = sbus_unmap_page,
400 .map_sg = sbus_map_sg,
401 .unmap_sg = sbus_unmap_sg,
402 .sync_sg_for_cpu = sbus_sync_sg_for_cpu,
403 .sync_sg_for_device = sbus_sync_sg_for_device,
404};
405
406struct dma_map_ops *dma_ops = &sbus_dma_ops;
407EXPORT_SYMBOL(dma_ops);
408
382static int __init sparc_register_ioport(void) 409static int __init sparc_register_ioport(void)
383{ 410{
384 register_proc_sparc_ioport(); 411 register_proc_sparc_ioport();
@@ -395,7 +422,8 @@ arch_initcall(sparc_register_ioport);
395/* Allocate and map kernel buffer using consistent mode DMA for a device. 422/* Allocate and map kernel buffer using consistent mode DMA for a device.
396 * hwdev should be valid struct pci_dev pointer for PCI devices. 423 * hwdev should be valid struct pci_dev pointer for PCI devices.
397 */ 424 */
398void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) 425static void *pci32_alloc_coherent(struct device *dev, size_t len,
426 dma_addr_t *pba, gfp_t gfp)
399{ 427{
400 unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; 428 unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
401 unsigned long va; 429 unsigned long va;
@@ -439,7 +467,6 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
439 *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ 467 *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
440 return (void *) res->start; 468 return (void *) res->start;
441} 469}
442EXPORT_SYMBOL(pci_alloc_consistent);
443 470
444/* Free and unmap a consistent DMA buffer. 471/* Free and unmap a consistent DMA buffer.
445 * cpu_addr is what was returned from pci_alloc_consistent, 472 * cpu_addr is what was returned from pci_alloc_consistent,
@@ -449,7 +476,8 @@ EXPORT_SYMBOL(pci_alloc_consistent);
449 * References to the memory and mappings associated with cpu_addr/dma_addr 476 * References to the memory and mappings associated with cpu_addr/dma_addr
450 * past this call are illegal. 477 * past this call are illegal.
451 */ 478 */
452void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba) 479static void pci32_free_coherent(struct device *dev, size_t n, void *p,
480 dma_addr_t ba)
453{ 481{
454 struct resource *res; 482 struct resource *res;
455 unsigned long pgp; 483 unsigned long pgp;
@@ -481,60 +509,18 @@ void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba)
481 509
482 free_pages(pgp, get_order(n)); 510 free_pages(pgp, get_order(n));
483} 511}
484EXPORT_SYMBOL(pci_free_consistent);
485
486/* Map a single buffer of the indicated size for DMA in streaming mode.
487 * The 32-bit bus address to use is returned.
488 *
489 * Once the device is given the dma address, the device owns this memory
490 * until either pci_unmap_single or pci_dma_sync_single_* is performed.
491 */
492dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
493 int direction)
494{
495 BUG_ON(direction == PCI_DMA_NONE);
496 /* IIep is write-through, not flushing. */
497 return virt_to_phys(ptr);
498}
499EXPORT_SYMBOL(pci_map_single);
500
501/* Unmap a single streaming mode DMA translation. The dma_addr and size
502 * must match what was provided for in a previous pci_map_single call. All
503 * other usages are undefined.
504 *
505 * After this call, reads by the cpu to the buffer are guaranteed to see
506 * whatever the device wrote there.
507 */
508void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size,
509 int direction)
510{
511 BUG_ON(direction == PCI_DMA_NONE);
512 if (direction != PCI_DMA_TODEVICE) {
513 mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
514 (size + PAGE_SIZE-1) & PAGE_MASK);
515 }
516}
517EXPORT_SYMBOL(pci_unmap_single);
518 512
519/* 513/*
520 * Same as pci_map_single, but with pages. 514 * Same as pci_map_single, but with pages.
521 */ 515 */
522dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, 516static dma_addr_t pci32_map_page(struct device *dev, struct page *page,
523 unsigned long offset, size_t size, int direction) 517 unsigned long offset, size_t size,
518 enum dma_data_direction dir,
519 struct dma_attrs *attrs)
524{ 520{
525 BUG_ON(direction == PCI_DMA_NONE);
526 /* IIep is write-through, not flushing. */ 521 /* IIep is write-through, not flushing. */
527 return page_to_phys(page) + offset; 522 return page_to_phys(page) + offset;
528} 523}
529EXPORT_SYMBOL(pci_map_page);
530
531void pci_unmap_page(struct pci_dev *hwdev,
532 dma_addr_t dma_address, size_t size, int direction)
533{
534 BUG_ON(direction == PCI_DMA_NONE);
535 /* mmu_inval_dma_area XXX */
536}
537EXPORT_SYMBOL(pci_unmap_page);
538 524
539/* Map a set of buffers described by scatterlist in streaming 525/* Map a set of buffers described by scatterlist in streaming
540 * mode for DMA. This is the scather-gather version of the 526 * mode for DMA. This is the scather-gather version of the
@@ -551,13 +537,13 @@ EXPORT_SYMBOL(pci_unmap_page);
551 * Device ownership issues as mentioned above for pci_map_single are 537 * Device ownership issues as mentioned above for pci_map_single are
552 * the same here. 538 * the same here.
553 */ 539 */
554int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, 540static int pci32_map_sg(struct device *device, struct scatterlist *sgl,
555 int direction) 541 int nents, enum dma_data_direction dir,
542 struct dma_attrs *attrs)
556{ 543{
557 struct scatterlist *sg; 544 struct scatterlist *sg;
558 int n; 545 int n;
559 546
560 BUG_ON(direction == PCI_DMA_NONE);
561 /* IIep is write-through, not flushing. */ 547 /* IIep is write-through, not flushing. */
562 for_each_sg(sgl, sg, nents, n) { 548 for_each_sg(sgl, sg, nents, n) {
563 BUG_ON(page_address(sg_page(sg)) == NULL); 549 BUG_ON(page_address(sg_page(sg)) == NULL);
@@ -566,20 +552,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
566 } 552 }
567 return nents; 553 return nents;
568} 554}
569EXPORT_SYMBOL(pci_map_sg);
570 555
571/* Unmap a set of streaming mode DMA translations. 556/* Unmap a set of streaming mode DMA translations.
572 * Again, cpu read rules concerning calls here are the same as for 557 * Again, cpu read rules concerning calls here are the same as for
573 * pci_unmap_single() above. 558 * pci_unmap_single() above.
574 */ 559 */
575void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, 560static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl,
576 int direction) 561 int nents, enum dma_data_direction dir,
562 struct dma_attrs *attrs)
577{ 563{
578 struct scatterlist *sg; 564 struct scatterlist *sg;
579 int n; 565 int n;
580 566
581 BUG_ON(direction == PCI_DMA_NONE); 567 if (dir != PCI_DMA_TODEVICE) {
582 if (direction != PCI_DMA_TODEVICE) {
583 for_each_sg(sgl, sg, nents, n) { 568 for_each_sg(sgl, sg, nents, n) {
584 BUG_ON(page_address(sg_page(sg)) == NULL); 569 BUG_ON(page_address(sg_page(sg)) == NULL);
585 mmu_inval_dma_area( 570 mmu_inval_dma_area(
@@ -588,7 +573,6 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
588 } 573 }
589 } 574 }
590} 575}
591EXPORT_SYMBOL(pci_unmap_sg);
592 576
593/* Make physical memory consistent for a single 577/* Make physical memory consistent for a single
594 * streaming mode DMA translation before or after a transfer. 578 * streaming mode DMA translation before or after a transfer.
@@ -600,25 +584,23 @@ EXPORT_SYMBOL(pci_unmap_sg);
600 * must first perform a pci_dma_sync_for_device, and then the 584 * must first perform a pci_dma_sync_for_device, and then the
601 * device again owns the buffer. 585 * device again owns the buffer.
602 */ 586 */
603void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) 587static void pci32_sync_single_for_cpu(struct device *dev, dma_addr_t ba,
588 size_t size, enum dma_data_direction dir)
604{ 589{
605 BUG_ON(direction == PCI_DMA_NONE); 590 if (dir != PCI_DMA_TODEVICE) {
606 if (direction != PCI_DMA_TODEVICE) {
607 mmu_inval_dma_area((unsigned long)phys_to_virt(ba), 591 mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
608 (size + PAGE_SIZE-1) & PAGE_MASK); 592 (size + PAGE_SIZE-1) & PAGE_MASK);
609 } 593 }
610} 594}
611EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
612 595
613void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) 596static void pci32_sync_single_for_device(struct device *dev, dma_addr_t ba,
597 size_t size, enum dma_data_direction dir)
614{ 598{
615 BUG_ON(direction == PCI_DMA_NONE); 599 if (dir != PCI_DMA_TODEVICE) {
616 if (direction != PCI_DMA_TODEVICE) {
617 mmu_inval_dma_area((unsigned long)phys_to_virt(ba), 600 mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
618 (size + PAGE_SIZE-1) & PAGE_MASK); 601 (size + PAGE_SIZE-1) & PAGE_MASK);
619 } 602 }
620} 603}
621EXPORT_SYMBOL(pci_dma_sync_single_for_device);
622 604
623/* Make physical memory consistent for a set of streaming 605/* Make physical memory consistent for a set of streaming
624 * mode DMA translations after a transfer. 606 * mode DMA translations after a transfer.
@@ -626,13 +608,13 @@ EXPORT_SYMBOL(pci_dma_sync_single_for_device);
626 * The same as pci_dma_sync_single_* but for a scatter-gather list, 608 * The same as pci_dma_sync_single_* but for a scatter-gather list,
627 * same rules and usage. 609 * same rules and usage.
628 */ 610 */
629void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) 611static void pci32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
612 int nents, enum dma_data_direction dir)
630{ 613{
631 struct scatterlist *sg; 614 struct scatterlist *sg;
632 int n; 615 int n;
633 616
634 BUG_ON(direction == PCI_DMA_NONE); 617 if (dir != PCI_DMA_TODEVICE) {
635 if (direction != PCI_DMA_TODEVICE) {
636 for_each_sg(sgl, sg, nents, n) { 618 for_each_sg(sgl, sg, nents, n) {
637 BUG_ON(page_address(sg_page(sg)) == NULL); 619 BUG_ON(page_address(sg_page(sg)) == NULL);
638 mmu_inval_dma_area( 620 mmu_inval_dma_area(
@@ -641,15 +623,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
641 } 623 }
642 } 624 }
643} 625}
644EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
645 626
646void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) 627static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *sgl,
628 int nents, enum dma_data_direction dir)
647{ 629{
648 struct scatterlist *sg; 630 struct scatterlist *sg;
649 int n; 631 int n;
650 632
651 BUG_ON(direction == PCI_DMA_NONE); 633 if (dir != PCI_DMA_TODEVICE) {
652 if (direction != PCI_DMA_TODEVICE) {
653 for_each_sg(sgl, sg, nents, n) { 634 for_each_sg(sgl, sg, nents, n) {
654 BUG_ON(page_address(sg_page(sg)) == NULL); 635 BUG_ON(page_address(sg_page(sg)) == NULL);
655 mmu_inval_dma_area( 636 mmu_inval_dma_area(
@@ -658,31 +639,78 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
658 } 639 }
659 } 640 }
660} 641}
661EXPORT_SYMBOL(pci_dma_sync_sg_for_device); 642
643struct dma_map_ops pci32_dma_ops = {
644 .alloc_coherent = pci32_alloc_coherent,
645 .free_coherent = pci32_free_coherent,
646 .map_page = pci32_map_page,
647 .map_sg = pci32_map_sg,
648 .unmap_sg = pci32_unmap_sg,
649 .sync_single_for_cpu = pci32_sync_single_for_cpu,
650 .sync_single_for_device = pci32_sync_single_for_device,
651 .sync_sg_for_cpu = pci32_sync_sg_for_cpu,
652 .sync_sg_for_device = pci32_sync_sg_for_device,
653};
654EXPORT_SYMBOL(pci32_dma_ops);
655
662#endif /* CONFIG_PCI */ 656#endif /* CONFIG_PCI */
663 657
658/*
659 * Return whether the given PCI device DMA address mask can be
660 * supported properly. For example, if your device can only drive the
661 * low 24-bits during PCI bus mastering, then you would pass
662 * 0x00ffffff as the mask to this function.
663 */
664int dma_supported(struct device *dev, u64 mask)
665{
666#ifdef CONFIG_PCI
667 if (dev->bus == &pci_bus_type)
668 return 1;
669#endif
670 return 0;
671}
672EXPORT_SYMBOL(dma_supported);
673
674int dma_set_mask(struct device *dev, u64 dma_mask)
675{
676#ifdef CONFIG_PCI
677 if (dev->bus == &pci_bus_type)
678 return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
679#endif
680 return -EOPNOTSUPP;
681}
682EXPORT_SYMBOL(dma_set_mask);
683
684
664#ifdef CONFIG_PROC_FS 685#ifdef CONFIG_PROC_FS
665 686
666static int 687static int sparc_io_proc_show(struct seq_file *m, void *v)
667_sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof,
668 void *data)
669{ 688{
670 char *p = buf, *e = buf + length; 689 struct resource *root = m->private, *r;
671 struct resource *r;
672 const char *nm; 690 const char *nm;
673 691
674 for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) { 692 for (r = root->child; r != NULL; r = r->sibling) {
675 if (p + 32 >= e) /* Better than nothing */
676 break;
677 if ((nm = r->name) == 0) nm = "???"; 693 if ((nm = r->name) == 0) nm = "???";
678 p += sprintf(p, "%016llx-%016llx: %s\n", 694 seq_printf(m, "%016llx-%016llx: %s\n",
679 (unsigned long long)r->start, 695 (unsigned long long)r->start,
680 (unsigned long long)r->end, nm); 696 (unsigned long long)r->end, nm);
681 } 697 }
682 698
683 return p-buf; 699 return 0;
684} 700}
685 701
702static int sparc_io_proc_open(struct inode *inode, struct file *file)
703{
704 return single_open(file, sparc_io_proc_show, PDE(inode)->data);
705}
706
707static const struct file_operations sparc_io_proc_fops = {
708 .owner = THIS_MODULE,
709 .open = sparc_io_proc_open,
710 .read = seq_read,
711 .llseek = seq_lseek,
712 .release = single_release,
713};
686#endif /* CONFIG_PROC_FS */ 714#endif /* CONFIG_PROC_FS */
687 715
688/* 716/*
@@ -707,7 +735,7 @@ static struct resource *_sparc_find_resource(struct resource *root,
707static void register_proc_sparc_ioport(void) 735static void register_proc_sparc_ioport(void)
708{ 736{
709#ifdef CONFIG_PROC_FS 737#ifdef CONFIG_PROC_FS
710 create_proc_read_entry("io_map",0,NULL,_sparc_io_get_info,&sparc_iomap); 738 proc_create_data("io_map", 0, NULL, &sparc_io_proc_fops, &sparc_iomap);
711 create_proc_read_entry("dvma_map",0,NULL,_sparc_io_get_info,&_sparc_dvma); 739 proc_create_data("dvma_map", 0, NULL, &sparc_io_proc_fops, &_sparc_dvma);
712#endif 740#endif
713} 741}
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index ad800b80c718..e1af43728329 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -45,6 +45,7 @@
45#include <asm/pcic.h> 45#include <asm/pcic.h>
46#include <asm/cacheflush.h> 46#include <asm/cacheflush.h>
47#include <asm/irq_regs.h> 47#include <asm/irq_regs.h>
48#include <asm/leon.h>
48 49
49#include "kernel.h" 50#include "kernel.h"
50#include "irq.h" 51#include "irq.h"
@@ -661,6 +662,10 @@ void __init init_IRQ(void)
661 sun4d_init_IRQ(); 662 sun4d_init_IRQ();
662 break; 663 break;
663 664
665 case sparc_leon:
666 leon_init_IRQ();
667 break;
668
664 default: 669 default:
665 prom_printf("Cannot initialize IRQs on this Sun machine..."); 670 prom_printf("Cannot initialize IRQs on this Sun machine...");
666 break; 671 break;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
new file mode 100644
index 000000000000..54d8a5bd4824
--- /dev/null
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -0,0 +1,203 @@
1/*
2 * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
3 * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/errno.h>
9#include <linux/mutex.h>
10#include <linux/slab.h>
11#include <linux/of.h>
12#include <linux/of_platform.h>
13#include <linux/interrupt.h>
14#include <linux/of_device.h>
15#include <asm/oplib.h>
16#include <asm/timer.h>
17#include <asm/prom.h>
18#include <asm/leon.h>
19#include <asm/leon_amba.h>
20
21#include "prom.h"
22#include "irq.h"
23
24struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */
25struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */
26struct amba_apb_device leon_percpu_timer_dev[16];
27
28int leondebug_irq_disable;
29int leon_debug_irqout;
30static int dummy_master_l10_counter;
31
32unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */
33unsigned int sparc_leon_eirq;
34#define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
35
36/* Return the IRQ of the pending IRQ on the extended IRQ controller */
37int sparc_leon_eirq_get(int eirq, int cpu)
38{
39 return LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->intid[cpu]) & 0x1f;
40}
41
42irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id)
43{
44 printk(KERN_ERR "sparc_leon_eirq_isr: ERROR EXTENDED IRQ\n");
45 return IRQ_HANDLED;
46}
47
48/* The extended IRQ controller has been found, this function registers it */
49void sparc_leon_eirq_register(int eirq)
50{
51 int irq;
52
53 /* Register a "BAD" handler for this interrupt, it should never happen */
54 irq = request_irq(eirq, sparc_leon_eirq_isr,
55 (IRQF_DISABLED | SA_STATIC_ALLOC), "extirq", NULL);
56
57 if (irq) {
58 printk(KERN_ERR
59 "sparc_leon_eirq_register: unable to attach IRQ%d\n",
60 eirq);
61 } else {
62 sparc_leon_eirq = eirq;
63 }
64
65}
66
67static inline unsigned long get_irqmask(unsigned int irq)
68{
69 unsigned long mask;
70
71 if (!irq || ((irq > 0xf) && !sparc_leon_eirq)
72 || ((irq > 0x1f) && sparc_leon_eirq)) {
73 printk(KERN_ERR
74 "leon_get_irqmask: false irq number: %d\n", irq);
75 mask = 0;
76 } else {
77 mask = LEON_HARD_INT(irq);
78 }
79 return mask;
80}
81
82static void leon_enable_irq(unsigned int irq_nr)
83{
84 unsigned long mask, flags;
85 mask = get_irqmask(irq_nr);
86 local_irq_save(flags);
87 LEON3_BYPASS_STORE_PA(LEON_IMASK,
88 (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask)));
89 local_irq_restore(flags);
90}
91
92static void leon_disable_irq(unsigned int irq_nr)
93{
94 unsigned long mask, flags;
95 mask = get_irqmask(irq_nr);
96 local_irq_save(flags);
97 LEON3_BYPASS_STORE_PA(LEON_IMASK,
98 (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask)));
99 local_irq_restore(flags);
100
101}
102
103void __init leon_init_timers(irq_handler_t counter_fn)
104{
105 int irq;
106
107 leondebug_irq_disable = 0;
108 leon_debug_irqout = 0;
109 master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
110 dummy_master_l10_counter = 0;
111
112 if (leon3_gptimer_regs && leon3_irqctrl_regs) {
113 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
114 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
115 (((1000000 / 100) - 1)));
116 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
117
118 } else {
119 printk(KERN_ERR "No Timer/irqctrl found\n");
120 BUG();
121 }
122
123 irq = request_irq(leon3_gptimer_irq,
124 counter_fn,
125 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
126
127 if (irq) {
128 printk(KERN_ERR "leon_time_init: unable to attach IRQ%d\n",
129 LEON_INTERRUPT_TIMER1);
130 prom_halt();
131 }
132
133 if (leon3_gptimer_regs) {
134 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,
135 LEON3_GPTIMER_EN |
136 LEON3_GPTIMER_RL |
137 LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
138 }
139}
140
141void leon_clear_clock_irq(void)
142{
143}
144
145void leon_load_profile_irq(int cpu, unsigned int limit)
146{
147 BUG();
148}
149
150
151
152
153void __init leon_trans_init(struct device_node *dp)
154{
155 if (strcmp(dp->type, "cpu") == 0 && strcmp(dp->name, "<NULL>") == 0) {
156 struct property *p;
157 p = of_find_property(dp, "mid", (void *)0);
158 if (p) {
159 int mid;
160 dp->name = prom_early_alloc(5 + 1);
161 memcpy(&mid, p->value, p->length);
162 sprintf((char *)dp->name, "cpu%.2d", mid);
163 }
164 }
165}
166
167void __initdata (*prom_amba_init)(struct device_node *dp, struct device_node ***nextp) = 0;
168
169void __init leon_node_init(struct device_node *dp, struct device_node ***nextp)
170{
171 if (prom_amba_init &&
172 strcmp(dp->type, "ambapp") == 0 &&
173 strcmp(dp->name, "ambapp0") == 0) {
174 prom_amba_init(dp, nextp);
175 }
176}
177
178void __init leon_init_IRQ(void)
179{
180 sparc_init_timers = leon_init_timers;
181
182 BTFIXUPSET_CALL(enable_irq, leon_enable_irq, BTFIXUPCALL_NORM);
183 BTFIXUPSET_CALL(disable_irq, leon_disable_irq, BTFIXUPCALL_NORM);
184 BTFIXUPSET_CALL(enable_pil_irq, leon_enable_irq, BTFIXUPCALL_NORM);
185 BTFIXUPSET_CALL(disable_pil_irq, leon_disable_irq, BTFIXUPCALL_NORM);
186
187 BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq,
188 BTFIXUPCALL_NORM);
189 BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq,
190 BTFIXUPCALL_NOP);
191
192#ifdef CONFIG_SMP
193 BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM);
194 BTFIXUPSET_CALL(clear_cpu_int, leon_clear_ipi, BTFIXUPCALL_NORM);
195 BTFIXUPSET_CALL(set_irq_udt, leon_set_udt, BTFIXUPCALL_NORM);
196#endif
197
198}
199
200void __init leon_init(void)
201{
202 prom_build_more = &leon_node_init;
203}
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index b75bf502cd42..378eb53e0776 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -19,6 +19,7 @@
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/smp.h> 20#include <linux/smp.h>
21 21
22#include <asm/perf_counter.h>
22#include <asm/ptrace.h> 23#include <asm/ptrace.h>
23#include <asm/local.h> 24#include <asm/local.h>
24#include <asm/pcr.h> 25#include <asm/pcr.h>
@@ -31,13 +32,19 @@
31 * level 14 as our IRQ off level. 32 * level 14 as our IRQ off level.
32 */ 33 */
33 34
34static int nmi_watchdog_active;
35static int panic_on_timeout; 35static int panic_on_timeout;
36 36
37int nmi_usable; 37/* nmi_active:
38EXPORT_SYMBOL_GPL(nmi_usable); 38 * >0: the NMI watchdog is active, but can be disabled
39 * <0: the NMI watchdog has not been set up, and cannot be enabled
40 * 0: the NMI watchdog is disabled, but can be enabled
41 */
42atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */
43EXPORT_SYMBOL(nmi_active);
39 44
40static unsigned int nmi_hz = HZ; 45static unsigned int nmi_hz = HZ;
46static DEFINE_PER_CPU(short, wd_enabled);
47static int endflag __initdata;
41 48
42static DEFINE_PER_CPU(unsigned int, last_irq_sum); 49static DEFINE_PER_CPU(unsigned int, last_irq_sum);
43static DEFINE_PER_CPU(local_t, alert_counter); 50static DEFINE_PER_CPU(local_t, alert_counter);
@@ -45,7 +52,7 @@ static DEFINE_PER_CPU(int, nmi_touch);
45 52
46void touch_nmi_watchdog(void) 53void touch_nmi_watchdog(void)
47{ 54{
48 if (nmi_watchdog_active) { 55 if (atomic_read(&nmi_active)) {
49 int cpu; 56 int cpu;
50 57
51 for_each_present_cpu(cpu) { 58 for_each_present_cpu(cpu) {
@@ -78,6 +85,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
78 if (do_panic || panic_on_oops) 85 if (do_panic || panic_on_oops)
79 panic("Non maskable interrupt"); 86 panic("Non maskable interrupt");
80 87
88 nmi_exit();
81 local_irq_enable(); 89 local_irq_enable();
82 do_exit(SIGBUS); 90 do_exit(SIGBUS);
83} 91}
@@ -92,6 +100,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
92 100
93 local_cpu_data().__nmi_count++; 101 local_cpu_data().__nmi_count++;
94 102
103 nmi_enter();
104
95 if (notify_die(DIE_NMI, "nmi", regs, 0, 105 if (notify_die(DIE_NMI, "nmi", regs, 0,
96 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) 106 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
97 touched = 1; 107 touched = 1;
@@ -110,10 +120,12 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
110 __get_cpu_var(last_irq_sum) = sum; 120 __get_cpu_var(last_irq_sum) = sum;
111 local_set(&__get_cpu_var(alert_counter), 0); 121 local_set(&__get_cpu_var(alert_counter), 0);
112 } 122 }
113 if (nmi_usable) { 123 if (__get_cpu_var(wd_enabled)) {
114 write_pic(picl_value(nmi_hz)); 124 write_pic(picl_value(nmi_hz));
115 pcr_ops->write(pcr_enable); 125 pcr_ops->write(pcr_enable);
116 } 126 }
127
128 nmi_exit();
117} 129}
118 130
119static inline unsigned int get_nmi_count(int cpu) 131static inline unsigned int get_nmi_count(int cpu)
@@ -121,8 +133,6 @@ static inline unsigned int get_nmi_count(int cpu)
121 return cpu_data(cpu).__nmi_count; 133 return cpu_data(cpu).__nmi_count;
122} 134}
123 135
124static int endflag __initdata;
125
126static __init void nmi_cpu_busy(void *data) 136static __init void nmi_cpu_busy(void *data)
127{ 137{
128 local_irq_enable_in_hardirq(); 138 local_irq_enable_in_hardirq();
@@ -143,12 +153,15 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count)
143 printk(KERN_WARNING 153 printk(KERN_WARNING
144 "and attach the output of the 'dmesg' command.\n"); 154 "and attach the output of the 'dmesg' command.\n");
145 155
146 nmi_usable = 0; 156 per_cpu(wd_enabled, cpu) = 0;
157 atomic_dec(&nmi_active);
147} 158}
148 159
149static void stop_watchdog(void *unused) 160void stop_nmi_watchdog(void *unused)
150{ 161{
151 pcr_ops->write(PCR_PIC_PRIV); 162 pcr_ops->write(PCR_PIC_PRIV);
163 __get_cpu_var(wd_enabled) = 0;
164 atomic_dec(&nmi_active);
152} 165}
153 166
154static int __init check_nmi_watchdog(void) 167static int __init check_nmi_watchdog(void)
@@ -156,6 +169,9 @@ static int __init check_nmi_watchdog(void)
156 unsigned int *prev_nmi_count; 169 unsigned int *prev_nmi_count;
157 int cpu, err; 170 int cpu, err;
158 171
172 if (!atomic_read(&nmi_active))
173 return 0;
174
159 prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL); 175 prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL);
160 if (!prev_nmi_count) { 176 if (!prev_nmi_count) {
161 err = -ENOMEM; 177 err = -ENOMEM;
@@ -172,12 +188,15 @@ static int __init check_nmi_watchdog(void)
172 mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ 188 mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */
173 189
174 for_each_online_cpu(cpu) { 190 for_each_online_cpu(cpu) {
191 if (!per_cpu(wd_enabled, cpu))
192 continue;
175 if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) 193 if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
176 report_broken_nmi(cpu, prev_nmi_count); 194 report_broken_nmi(cpu, prev_nmi_count);
177 } 195 }
178 endflag = 1; 196 endflag = 1;
179 if (!nmi_usable) { 197 if (!atomic_read(&nmi_active)) {
180 kfree(prev_nmi_count); 198 kfree(prev_nmi_count);
199 atomic_set(&nmi_active, -1);
181 err = -ENODEV; 200 err = -ENODEV;
182 goto error; 201 goto error;
183 } 202 }
@@ -188,12 +207,26 @@ static int __init check_nmi_watchdog(void)
188 kfree(prev_nmi_count); 207 kfree(prev_nmi_count);
189 return 0; 208 return 0;
190error: 209error:
191 on_each_cpu(stop_watchdog, NULL, 1); 210 on_each_cpu(stop_nmi_watchdog, NULL, 1);
192 return err; 211 return err;
193} 212}
194 213
195static void start_watchdog(void *unused) 214void start_nmi_watchdog(void *unused)
196{ 215{
216 __get_cpu_var(wd_enabled) = 1;
217 atomic_inc(&nmi_active);
218
219 pcr_ops->write(PCR_PIC_PRIV);
220 write_pic(picl_value(nmi_hz));
221
222 pcr_ops->write(pcr_enable);
223}
224
225static void nmi_adjust_hz_one(void *unused)
226{
227 if (!__get_cpu_var(wd_enabled))
228 return;
229
197 pcr_ops->write(PCR_PIC_PRIV); 230 pcr_ops->write(PCR_PIC_PRIV);
198 write_pic(picl_value(nmi_hz)); 231 write_pic(picl_value(nmi_hz));
199 232
@@ -203,13 +236,13 @@ static void start_watchdog(void *unused)
203void nmi_adjust_hz(unsigned int new_hz) 236void nmi_adjust_hz(unsigned int new_hz)
204{ 237{
205 nmi_hz = new_hz; 238 nmi_hz = new_hz;
206 on_each_cpu(start_watchdog, NULL, 1); 239 on_each_cpu(nmi_adjust_hz_one, NULL, 1);
207} 240}
208EXPORT_SYMBOL_GPL(nmi_adjust_hz); 241EXPORT_SYMBOL_GPL(nmi_adjust_hz);
209 242
210static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p) 243static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p)
211{ 244{
212 on_each_cpu(stop_watchdog, NULL, 1); 245 on_each_cpu(stop_nmi_watchdog, NULL, 1);
213 return 0; 246 return 0;
214} 247}
215 248
@@ -221,18 +254,19 @@ int __init nmi_init(void)
221{ 254{
222 int err; 255 int err;
223 256
224 nmi_usable = 1; 257 on_each_cpu(start_nmi_watchdog, NULL, 1);
225
226 on_each_cpu(start_watchdog, NULL, 1);
227 258
228 err = check_nmi_watchdog(); 259 err = check_nmi_watchdog();
229 if (!err) { 260 if (!err) {
230 err = register_reboot_notifier(&nmi_reboot_notifier); 261 err = register_reboot_notifier(&nmi_reboot_notifier);
231 if (err) { 262 if (err) {
232 nmi_usable = 0; 263 on_each_cpu(stop_nmi_watchdog, NULL, 1);
233 on_each_cpu(stop_watchdog, NULL, 1); 264 atomic_set(&nmi_active, -1);
234 } 265 }
235 } 266 }
267 if (!err)
268 init_hw_perf_counters();
269
236 return err; 270 return err;
237} 271}
238 272
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 90396702ea2c..4c26eb59e742 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -9,6 +9,8 @@
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/of_platform.h> 11#include <linux/of_platform.h>
12#include <asm/leon.h>
13#include <asm/leon_amba.h>
12 14
13#include "of_device_common.h" 15#include "of_device_common.h"
14 16
@@ -97,6 +99,35 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
97 return IORESOURCE_MEM; 99 return IORESOURCE_MEM;
98} 100}
99 101
102 /*
103 * AMBAPP bus specific translator
104 */
105
106static int of_bus_ambapp_match(struct device_node *np)
107{
108 return !strcmp(np->name, "ambapp");
109}
110
111static void of_bus_ambapp_count_cells(struct device_node *child,
112 int *addrc, int *sizec)
113{
114 if (addrc)
115 *addrc = 1;
116 if (sizec)
117 *sizec = 1;
118}
119
120static int of_bus_ambapp_map(u32 *addr, const u32 *range,
121 int na, int ns, int pna)
122{
123 return of_bus_default_map(addr, range, na, ns, pna);
124}
125
126static unsigned long of_bus_ambapp_get_flags(const u32 *addr,
127 unsigned long flags)
128{
129 return IORESOURCE_MEM;
130}
100 131
101/* 132/*
102 * Array of bus specific translators 133 * Array of bus specific translators
@@ -121,6 +152,15 @@ static struct of_bus of_busses[] = {
121 .map = of_bus_default_map, 152 .map = of_bus_default_map,
122 .get_flags = of_bus_sbus_get_flags, 153 .get_flags = of_bus_sbus_get_flags,
123 }, 154 },
155 /* AMBA */
156 {
157 .name = "ambapp",
158 .addr_prop_name = "reg",
159 .match = of_bus_ambapp_match,
160 .count_cells = of_bus_ambapp_count_cells,
161 .map = of_bus_ambapp_map,
162 .get_flags = of_bus_ambapp_get_flags,
163 },
124 /* Default */ 164 /* Default */
125 { 165 {
126 .name = "default", 166 .name = "default",
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 57859ad23547..c68648662802 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -1039,7 +1039,7 @@ static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
1039 pci_dev_put(ali_isa_bridge); 1039 pci_dev_put(ali_isa_bridge);
1040} 1040}
1041 1041
1042int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) 1042int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask)
1043{ 1043{
1044 u64 dma_addr_mask; 1044 u64 dma_addr_mask;
1045 1045
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 2485eaa23101..23c33ff9c31e 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -232,7 +232,8 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu,
232 232
233static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, 233static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page,
234 unsigned long offset, size_t sz, 234 unsigned long offset, size_t sz,
235 enum dma_data_direction direction) 235 enum dma_data_direction direction,
236 struct dma_attrs *attrs)
236{ 237{
237 struct iommu *iommu; 238 struct iommu *iommu;
238 unsigned long flags, npages, oaddr; 239 unsigned long flags, npages, oaddr;
@@ -296,7 +297,8 @@ iommu_map_fail:
296} 297}
297 298
298static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, 299static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr,
299 size_t sz, enum dma_data_direction direction) 300 size_t sz, enum dma_data_direction direction,
301 struct dma_attrs *attrs)
300{ 302{
301 struct pci_pbm_info *pbm; 303 struct pci_pbm_info *pbm;
302 struct iommu *iommu; 304 struct iommu *iommu;
@@ -336,7 +338,8 @@ static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr,
336} 338}
337 339
338static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, 340static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
339 int nelems, enum dma_data_direction direction) 341 int nelems, enum dma_data_direction direction,
342 struct dma_attrs *attrs)
340{ 343{
341 struct scatterlist *s, *outs, *segstart; 344 struct scatterlist *s, *outs, *segstart;
342 unsigned long flags, handle, prot; 345 unsigned long flags, handle, prot;
@@ -478,7 +481,8 @@ iommu_map_failed:
478} 481}
479 482
480static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, 483static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
481 int nelems, enum dma_data_direction direction) 484 int nelems, enum dma_data_direction direction,
485 struct dma_attrs *attrs)
482{ 486{
483 struct pci_pbm_info *pbm; 487 struct pci_pbm_info *pbm;
484 struct scatterlist *sg; 488 struct scatterlist *sg;
@@ -521,29 +525,13 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
521 spin_unlock_irqrestore(&iommu->lock, flags); 525 spin_unlock_irqrestore(&iommu->lock, flags);
522} 526}
523 527
524static void dma_4v_sync_single_for_cpu(struct device *dev, 528static struct dma_map_ops sun4v_dma_ops = {
525 dma_addr_t bus_addr, size_t sz,
526 enum dma_data_direction direction)
527{
528 /* Nothing to do... */
529}
530
531static void dma_4v_sync_sg_for_cpu(struct device *dev,
532 struct scatterlist *sglist, int nelems,
533 enum dma_data_direction direction)
534{
535 /* Nothing to do... */
536}
537
538static const struct dma_ops sun4v_dma_ops = {
539 .alloc_coherent = dma_4v_alloc_coherent, 529 .alloc_coherent = dma_4v_alloc_coherent,
540 .free_coherent = dma_4v_free_coherent, 530 .free_coherent = dma_4v_free_coherent,
541 .map_page = dma_4v_map_page, 531 .map_page = dma_4v_map_page,
542 .unmap_page = dma_4v_unmap_page, 532 .unmap_page = dma_4v_unmap_page,
543 .map_sg = dma_4v_map_sg, 533 .map_sg = dma_4v_map_sg,
544 .unmap_sg = dma_4v_unmap_sg, 534 .unmap_sg = dma_4v_unmap_sg,
545 .sync_single_for_cpu = dma_4v_sync_single_for_cpu,
546 .sync_sg_for_cpu = dma_4v_sync_sg_for_cpu,
547}; 535};
548 536
549static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, 537static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm,
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
index 1ae8cdd7e703..68ff00107073 100644
--- a/arch/sparc/kernel/pcr.c
+++ b/arch/sparc/kernel/pcr.c
@@ -7,6 +7,8 @@
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/irq.h> 8#include <linux/irq.h>
9 9
10#include <linux/perf_counter.h>
11
10#include <asm/pil.h> 12#include <asm/pil.h>
11#include <asm/pcr.h> 13#include <asm/pcr.h>
12#include <asm/nmi.h> 14#include <asm/nmi.h>
@@ -34,10 +36,20 @@ unsigned int picl_shift;
34 */ 36 */
35void deferred_pcr_work_irq(int irq, struct pt_regs *regs) 37void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
36{ 38{
39 struct pt_regs *old_regs;
40
37 clear_softint(1 << PIL_DEFERRED_PCR_WORK); 41 clear_softint(1 << PIL_DEFERRED_PCR_WORK);
42
43 old_regs = set_irq_regs(regs);
44 irq_enter();
45#ifdef CONFIG_PERF_COUNTERS
46 perf_counter_do_pending();
47#endif
48 irq_exit();
49 set_irq_regs(old_regs);
38} 50}
39 51
40void schedule_deferred_pcr_work(void) 52void set_perf_counter_pending(void)
41{ 53{
42 set_softint(1 << PIL_DEFERRED_PCR_WORK); 54 set_softint(1 << PIL_DEFERRED_PCR_WORK);
43} 55}
diff --git a/arch/sparc/kernel/perf_counter.c b/arch/sparc/kernel/perf_counter.c
new file mode 100644
index 000000000000..09de4035eaa9
--- /dev/null
+++ b/arch/sparc/kernel/perf_counter.c
@@ -0,0 +1,557 @@
1/* Performance counter support for sparc64.
2 *
3 * Copyright (C) 2009 David S. Miller <davem@davemloft.net>
4 *
5 * This code is based almost entirely upon the x86 perf counter
6 * code, which is:
7 *
8 * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
9 * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
10 * Copyright (C) 2009 Jaswinder Singh Rajput
11 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
12 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
13 */
14
15#include <linux/perf_counter.h>
16#include <linux/kprobes.h>
17#include <linux/kernel.h>
18#include <linux/kdebug.h>
19#include <linux/mutex.h>
20
21#include <asm/cpudata.h>
22#include <asm/atomic.h>
23#include <asm/nmi.h>
24#include <asm/pcr.h>
25
26/* Sparc64 chips have two performance counters, 32-bits each, with
27 * overflow interrupts generated on transition from 0xffffffff to 0.
28 * The counters are accessed in one go using a 64-bit register.
29 *
30 * Both counters are controlled using a single control register. The
31 * only way to stop all sampling is to clear all of the context (user,
32 * supervisor, hypervisor) sampling enable bits. But these bits apply
33 * to both counters, thus the two counters can't be enabled/disabled
34 * individually.
35 *
36 * The control register has two event fields, one for each of the two
37 * counters. It's thus nearly impossible to have one counter going
38 * while keeping the other one stopped. Therefore it is possible to
39 * get overflow interrupts for counters not currently "in use" and
40 * that condition must be checked in the overflow interrupt handler.
41 *
42 * So we use a hack, in that we program inactive counters with the
43 * "sw_count0" and "sw_count1" events. These count how many times
44 * the instruction "sethi %hi(0xfc000), %g0" is executed. It's an
45 * unusual way to encode a NOP and therefore will not trigger in
46 * normal code.
47 */
48
49#define MAX_HWCOUNTERS 2
50#define MAX_PERIOD ((1UL << 32) - 1)
51
52#define PIC_UPPER_INDEX 0
53#define PIC_LOWER_INDEX 1
54
55struct cpu_hw_counters {
56 struct perf_counter *counters[MAX_HWCOUNTERS];
57 unsigned long used_mask[BITS_TO_LONGS(MAX_HWCOUNTERS)];
58 unsigned long active_mask[BITS_TO_LONGS(MAX_HWCOUNTERS)];
59 int enabled;
60};
61DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { .enabled = 1, };
62
63struct perf_event_map {
64 u16 encoding;
65 u8 pic_mask;
66#define PIC_NONE 0x00
67#define PIC_UPPER 0x01
68#define PIC_LOWER 0x02
69};
70
71struct sparc_pmu {
72 const struct perf_event_map *(*event_map)(int);
73 int max_events;
74 int upper_shift;
75 int lower_shift;
76 int event_mask;
77 int hv_bit;
78 int irq_bit;
79 int upper_nop;
80 int lower_nop;
81};
82
83static const struct perf_event_map ultra3i_perfmon_event_map[] = {
84 [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER },
85 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER },
86 [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER },
87 [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER },
88};
89
90static const struct perf_event_map *ultra3i_event_map(int event)
91{
92 return &ultra3i_perfmon_event_map[event];
93}
94
95static const struct sparc_pmu ultra3i_pmu = {
96 .event_map = ultra3i_event_map,
97 .max_events = ARRAY_SIZE(ultra3i_perfmon_event_map),
98 .upper_shift = 11,
99 .lower_shift = 4,
100 .event_mask = 0x3f,
101 .upper_nop = 0x1c,
102 .lower_nop = 0x14,
103};
104
105static const struct perf_event_map niagara2_perfmon_event_map[] = {
106 [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER },
107 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER },
108 [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0208, PIC_UPPER | PIC_LOWER },
109 [PERF_COUNT_HW_CACHE_MISSES] = { 0x0302, PIC_UPPER | PIC_LOWER },
110 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x0201, PIC_UPPER | PIC_LOWER },
111 [PERF_COUNT_HW_BRANCH_MISSES] = { 0x0202, PIC_UPPER | PIC_LOWER },
112};
113
114static const struct perf_event_map *niagara2_event_map(int event)
115{
116 return &niagara2_perfmon_event_map[event];
117}
118
119static const struct sparc_pmu niagara2_pmu = {
120 .event_map = niagara2_event_map,
121 .max_events = ARRAY_SIZE(niagara2_perfmon_event_map),
122 .upper_shift = 19,
123 .lower_shift = 6,
124 .event_mask = 0xfff,
125 .hv_bit = 0x8,
126 .irq_bit = 0x03,
127 .upper_nop = 0x220,
128 .lower_nop = 0x220,
129};
130
131static const struct sparc_pmu *sparc_pmu __read_mostly;
132
133static u64 event_encoding(u64 event, int idx)
134{
135 if (idx == PIC_UPPER_INDEX)
136 event <<= sparc_pmu->upper_shift;
137 else
138 event <<= sparc_pmu->lower_shift;
139 return event;
140}
141
142static u64 mask_for_index(int idx)
143{
144 return event_encoding(sparc_pmu->event_mask, idx);
145}
146
147static u64 nop_for_index(int idx)
148{
149 return event_encoding(idx == PIC_UPPER_INDEX ?
150 sparc_pmu->upper_nop :
151 sparc_pmu->lower_nop, idx);
152}
153
154static inline void sparc_pmu_enable_counter(struct hw_perf_counter *hwc,
155 int idx)
156{
157 u64 val, mask = mask_for_index(idx);
158
159 val = pcr_ops->read();
160 pcr_ops->write((val & ~mask) | hwc->config);
161}
162
163static inline void sparc_pmu_disable_counter(struct hw_perf_counter *hwc,
164 int idx)
165{
166 u64 mask = mask_for_index(idx);
167 u64 nop = nop_for_index(idx);
168 u64 val = pcr_ops->read();
169
170 pcr_ops->write((val & ~mask) | nop);
171}
172
173void hw_perf_enable(void)
174{
175 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
176 u64 val;
177 int i;
178
179 if (cpuc->enabled)
180 return;
181
182 cpuc->enabled = 1;
183 barrier();
184
185 val = pcr_ops->read();
186
187 for (i = 0; i < MAX_HWCOUNTERS; i++) {
188 struct perf_counter *cp = cpuc->counters[i];
189 struct hw_perf_counter *hwc;
190
191 if (!cp)
192 continue;
193 hwc = &cp->hw;
194 val |= hwc->config_base;
195 }
196
197 pcr_ops->write(val);
198}
199
200void hw_perf_disable(void)
201{
202 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
203 u64 val;
204
205 if (!cpuc->enabled)
206 return;
207
208 cpuc->enabled = 0;
209
210 val = pcr_ops->read();
211 val &= ~(PCR_UTRACE | PCR_STRACE |
212 sparc_pmu->hv_bit | sparc_pmu->irq_bit);
213 pcr_ops->write(val);
214}
215
216static u32 read_pmc(int idx)
217{
218 u64 val;
219
220 read_pic(val);
221 if (idx == PIC_UPPER_INDEX)
222 val >>= 32;
223
224 return val & 0xffffffff;
225}
226
227static void write_pmc(int idx, u64 val)
228{
229 u64 shift, mask, pic;
230
231 shift = 0;
232 if (idx == PIC_UPPER_INDEX)
233 shift = 32;
234
235 mask = ((u64) 0xffffffff) << shift;
236 val <<= shift;
237
238 read_pic(pic);
239 pic &= ~mask;
240 pic |= val;
241 write_pic(pic);
242}
243
244static int sparc_perf_counter_set_period(struct perf_counter *counter,
245 struct hw_perf_counter *hwc, int idx)
246{
247 s64 left = atomic64_read(&hwc->period_left);
248 s64 period = hwc->sample_period;
249 int ret = 0;
250
251 if (unlikely(left <= -period)) {
252 left = period;
253 atomic64_set(&hwc->period_left, left);
254 hwc->last_period = period;
255 ret = 1;
256 }
257
258 if (unlikely(left <= 0)) {
259 left += period;
260 atomic64_set(&hwc->period_left, left);
261 hwc->last_period = period;
262 ret = 1;
263 }
264 if (left > MAX_PERIOD)
265 left = MAX_PERIOD;
266
267 atomic64_set(&hwc->prev_count, (u64)-left);
268
269 write_pmc(idx, (u64)(-left) & 0xffffffff);
270
271 perf_counter_update_userpage(counter);
272
273 return ret;
274}
275
276static int sparc_pmu_enable(struct perf_counter *counter)
277{
278 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
279 struct hw_perf_counter *hwc = &counter->hw;
280 int idx = hwc->idx;
281
282 if (test_and_set_bit(idx, cpuc->used_mask))
283 return -EAGAIN;
284
285 sparc_pmu_disable_counter(hwc, idx);
286
287 cpuc->counters[idx] = counter;
288 set_bit(idx, cpuc->active_mask);
289
290 sparc_perf_counter_set_period(counter, hwc, idx);
291 sparc_pmu_enable_counter(hwc, idx);
292 perf_counter_update_userpage(counter);
293 return 0;
294}
295
296static u64 sparc_perf_counter_update(struct perf_counter *counter,
297 struct hw_perf_counter *hwc, int idx)
298{
299 int shift = 64 - 32;
300 u64 prev_raw_count, new_raw_count;
301 s64 delta;
302
303again:
304 prev_raw_count = atomic64_read(&hwc->prev_count);
305 new_raw_count = read_pmc(idx);
306
307 if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
308 new_raw_count) != prev_raw_count)
309 goto again;
310
311 delta = (new_raw_count << shift) - (prev_raw_count << shift);
312 delta >>= shift;
313
314 atomic64_add(delta, &counter->count);
315 atomic64_sub(delta, &hwc->period_left);
316
317 return new_raw_count;
318}
319
320static void sparc_pmu_disable(struct perf_counter *counter)
321{
322 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
323 struct hw_perf_counter *hwc = &counter->hw;
324 int idx = hwc->idx;
325
326 clear_bit(idx, cpuc->active_mask);
327 sparc_pmu_disable_counter(hwc, idx);
328
329 barrier();
330
331 sparc_perf_counter_update(counter, hwc, idx);
332 cpuc->counters[idx] = NULL;
333 clear_bit(idx, cpuc->used_mask);
334
335 perf_counter_update_userpage(counter);
336}
337
338static void sparc_pmu_read(struct perf_counter *counter)
339{
340 struct hw_perf_counter *hwc = &counter->hw;
341 sparc_perf_counter_update(counter, hwc, hwc->idx);
342}
343
344static void sparc_pmu_unthrottle(struct perf_counter *counter)
345{
346 struct hw_perf_counter *hwc = &counter->hw;
347 sparc_pmu_enable_counter(hwc, hwc->idx);
348}
349
350static atomic_t active_counters = ATOMIC_INIT(0);
351static DEFINE_MUTEX(pmc_grab_mutex);
352
353void perf_counter_grab_pmc(void)
354{
355 if (atomic_inc_not_zero(&active_counters))
356 return;
357
358 mutex_lock(&pmc_grab_mutex);
359 if (atomic_read(&active_counters) == 0) {
360 if (atomic_read(&nmi_active) > 0) {
361 on_each_cpu(stop_nmi_watchdog, NULL, 1);
362 BUG_ON(atomic_read(&nmi_active) != 0);
363 }
364 atomic_inc(&active_counters);
365 }
366 mutex_unlock(&pmc_grab_mutex);
367}
368
369void perf_counter_release_pmc(void)
370{
371 if (atomic_dec_and_mutex_lock(&active_counters, &pmc_grab_mutex)) {
372 if (atomic_read(&nmi_active) == 0)
373 on_each_cpu(start_nmi_watchdog, NULL, 1);
374 mutex_unlock(&pmc_grab_mutex);
375 }
376}
377
378static void hw_perf_counter_destroy(struct perf_counter *counter)
379{
380 perf_counter_release_pmc();
381}
382
383static int __hw_perf_counter_init(struct perf_counter *counter)
384{
385 struct perf_counter_attr *attr = &counter->attr;
386 struct hw_perf_counter *hwc = &counter->hw;
387 const struct perf_event_map *pmap;
388 u64 enc;
389
390 if (atomic_read(&nmi_active) < 0)
391 return -ENODEV;
392
393 if (attr->type != PERF_TYPE_HARDWARE)
394 return -EOPNOTSUPP;
395
396 if (attr->config >= sparc_pmu->max_events)
397 return -EINVAL;
398
399 perf_counter_grab_pmc();
400 counter->destroy = hw_perf_counter_destroy;
401
402 /* We save the enable bits in the config_base. So to
403 * turn off sampling just write 'config', and to enable
404 * things write 'config | config_base'.
405 */
406 hwc->config_base = sparc_pmu->irq_bit;
407 if (!attr->exclude_user)
408 hwc->config_base |= PCR_UTRACE;
409 if (!attr->exclude_kernel)
410 hwc->config_base |= PCR_STRACE;
411 if (!attr->exclude_hv)
412 hwc->config_base |= sparc_pmu->hv_bit;
413
414 if (!hwc->sample_period) {
415 hwc->sample_period = MAX_PERIOD;
416 hwc->last_period = hwc->sample_period;
417 atomic64_set(&hwc->period_left, hwc->sample_period);
418 }
419
420 pmap = sparc_pmu->event_map(attr->config);
421
422 enc = pmap->encoding;
423 if (pmap->pic_mask & PIC_UPPER) {
424 hwc->idx = PIC_UPPER_INDEX;
425 enc <<= sparc_pmu->upper_shift;
426 } else {
427 hwc->idx = PIC_LOWER_INDEX;
428 enc <<= sparc_pmu->lower_shift;
429 }
430
431 hwc->config |= enc;
432 return 0;
433}
434
435static const struct pmu pmu = {
436 .enable = sparc_pmu_enable,
437 .disable = sparc_pmu_disable,
438 .read = sparc_pmu_read,
439 .unthrottle = sparc_pmu_unthrottle,
440};
441
442const struct pmu *hw_perf_counter_init(struct perf_counter *counter)
443{
444 int err = __hw_perf_counter_init(counter);
445
446 if (err)
447 return ERR_PTR(err);
448 return &pmu;
449}
450
451void perf_counter_print_debug(void)
452{
453 unsigned long flags;
454 u64 pcr, pic;
455 int cpu;
456
457 if (!sparc_pmu)
458 return;
459
460 local_irq_save(flags);
461
462 cpu = smp_processor_id();
463
464 pcr = pcr_ops->read();
465 read_pic(pic);
466
467 pr_info("\n");
468 pr_info("CPU#%d: PCR[%016llx] PIC[%016llx]\n",
469 cpu, pcr, pic);
470
471 local_irq_restore(flags);
472}
473
474static int __kprobes perf_counter_nmi_handler(struct notifier_block *self,
475 unsigned long cmd, void *__args)
476{
477 struct die_args *args = __args;
478 struct perf_sample_data data;
479 struct cpu_hw_counters *cpuc;
480 struct pt_regs *regs;
481 int idx;
482
483 if (!atomic_read(&active_counters))
484 return NOTIFY_DONE;
485
486 switch (cmd) {
487 case DIE_NMI:
488 break;
489
490 default:
491 return NOTIFY_DONE;
492 }
493
494 regs = args->regs;
495
496 data.regs = regs;
497 data.addr = 0;
498
499 cpuc = &__get_cpu_var(cpu_hw_counters);
500 for (idx = 0; idx < MAX_HWCOUNTERS; idx++) {
501 struct perf_counter *counter = cpuc->counters[idx];
502 struct hw_perf_counter *hwc;
503 u64 val;
504
505 if (!test_bit(idx, cpuc->active_mask))
506 continue;
507 hwc = &counter->hw;
508 val = sparc_perf_counter_update(counter, hwc, idx);
509 if (val & (1ULL << 31))
510 continue;
511
512 data.period = counter->hw.last_period;
513 if (!sparc_perf_counter_set_period(counter, hwc, idx))
514 continue;
515
516 if (perf_counter_overflow(counter, 1, &data))
517 sparc_pmu_disable_counter(hwc, idx);
518 }
519
520 return NOTIFY_STOP;
521}
522
523static __read_mostly struct notifier_block perf_counter_nmi_notifier = {
524 .notifier_call = perf_counter_nmi_handler,
525};
526
527static bool __init supported_pmu(void)
528{
529 if (!strcmp(sparc_pmu_type, "ultra3i")) {
530 sparc_pmu = &ultra3i_pmu;
531 return true;
532 }
533 if (!strcmp(sparc_pmu_type, "niagara2")) {
534 sparc_pmu = &niagara2_pmu;
535 return true;
536 }
537 return false;
538}
539
540void __init init_hw_perf_counters(void)
541{
542 pr_info("Performance counters: ");
543
544 if (!supported_pmu()) {
545 pr_cont("No support for PMU type '%s'\n", sparc_pmu_type);
546 return;
547 }
548
549 pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
550
551 /* All sparc64 PMUs currently have 2 counters. But this simple
552 * driver only supports one active counter at a time.
553 */
554 perf_max_counters = 1;
555
556 register_die_notifier(&perf_counter_nmi_notifier);
557}
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 4041f94e7724..18d67854a1b8 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -251,7 +251,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp)
251 } 251 }
252} 252}
253 253
254void __trigger_all_cpu_backtrace(void) 254void arch_trigger_all_cpu_backtrace(void)
255{ 255{
256 struct thread_info *tp = current_thread_info(); 256 struct thread_info *tp = current_thread_info();
257 struct pt_regs *regs = get_irq_regs(); 257 struct pt_regs *regs = get_irq_regs();
@@ -304,7 +304,7 @@ void __trigger_all_cpu_backtrace(void)
304 304
305static void sysrq_handle_globreg(int key, struct tty_struct *tty) 305static void sysrq_handle_globreg(int key, struct tty_struct *tty)
306{ 306{
307 __trigger_all_cpu_backtrace(); 307 arch_trigger_all_cpu_backtrace();
308} 308}
309 309
310static struct sysrq_key_op sparc_globalreg_op = { 310static struct sysrq_key_op sparc_globalreg_op = {
diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c
index fe43e80772db..0a37e8cfd160 100644
--- a/arch/sparc/kernel/prom_32.c
+++ b/arch/sparc/kernel/prom_32.c
@@ -24,6 +24,8 @@
24 24
25#include <asm/prom.h> 25#include <asm/prom.h>
26#include <asm/oplib.h> 26#include <asm/oplib.h>
27#include <asm/leon.h>
28#include <asm/leon_amba.h>
27 29
28#include "prom.h" 30#include "prom.h"
29 31
@@ -131,6 +133,35 @@ static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
131 regs->which_io, regs->phys_addr); 133 regs->which_io, regs->phys_addr);
132} 134}
133 135
136/* "name:vendor:device@irq,addrlo" */
137static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
138{
139 struct amba_prom_registers *regs; unsigned int *intr;
140 unsigned int *device, *vendor;
141 struct property *prop;
142
143 prop = of_find_property(dp, "reg", NULL);
144 if (!prop)
145 return;
146 regs = prop->value;
147 prop = of_find_property(dp, "interrupts", NULL);
148 if (!prop)
149 return;
150 intr = prop->value;
151 prop = of_find_property(dp, "vendor", NULL);
152 if (!prop)
153 return;
154 vendor = prop->value;
155 prop = of_find_property(dp, "device", NULL);
156 if (!prop)
157 return;
158 device = prop->value;
159
160 sprintf(tmp_buf, "%s:%d:%d@%x,%x",
161 dp->name, *vendor, *device,
162 *intr, regs->phys_addr);
163}
164
134static void __init __build_path_component(struct device_node *dp, char *tmp_buf) 165static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
135{ 166{
136 struct device_node *parent = dp->parent; 167 struct device_node *parent = dp->parent;
@@ -143,6 +174,8 @@ static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
143 return sbus_path_component(dp, tmp_buf); 174 return sbus_path_component(dp, tmp_buf);
144 if (!strcmp(parent->type, "ebus")) 175 if (!strcmp(parent->type, "ebus"))
145 return ebus_path_component(dp, tmp_buf); 176 return ebus_path_component(dp, tmp_buf);
177 if (!strcmp(parent->type, "ambapp"))
178 return ambapp_path_component(dp, tmp_buf);
146 179
147 /* "isa" is handled with platform naming */ 180 /* "isa" is handled with platform naming */
148 } 181 }
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 0fb5789d43c8..138910c67206 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -22,9 +22,12 @@
22#include <linux/of.h> 22#include <linux/of.h>
23#include <asm/prom.h> 23#include <asm/prom.h>
24#include <asm/oplib.h> 24#include <asm/oplib.h>
25#include <asm/leon.h>
25 26
26#include "prom.h" 27#include "prom.h"
27 28
29void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
30
28struct device_node *of_console_device; 31struct device_node *of_console_device;
29EXPORT_SYMBOL(of_console_device); 32EXPORT_SYMBOL(of_console_device);
30 33
@@ -161,7 +164,7 @@ static struct property * __init build_one_prop(phandle node, char *prev,
161 name = prom_nextprop(node, prev, p->name); 164 name = prom_nextprop(node, prev, p->name);
162 } 165 }
163 166
164 if (strlen(name) == 0) { 167 if (!name || strlen(name) == 0) {
165 tmp = p; 168 tmp = p;
166 return NULL; 169 return NULL;
167 } 170 }
@@ -242,7 +245,7 @@ static struct device_node * __init prom_create_node(phandle node,
242 return dp; 245 return dp;
243} 246}
244 247
245static char * __init build_full_name(struct device_node *dp) 248char * __init build_full_name(struct device_node *dp)
246{ 249{
247 int len, ourlen, plen; 250 int len, ourlen, plen;
248 char *n; 251 char *n;
@@ -289,6 +292,9 @@ static struct device_node * __init prom_build_tree(struct device_node *parent,
289 292
290 dp->child = prom_build_tree(dp, prom_getchild(node), nextp); 293 dp->child = prom_build_tree(dp, prom_getchild(node), nextp);
291 294
295 if (prom_build_more)
296 prom_build_more(dp, nextp);
297
292 node = prom_getsibling(node); 298 node = prom_getsibling(node);
293 } 299 }
294 300
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 998cadb4e7f2..16a47ffe03c1 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -235,6 +235,8 @@ void __init setup_arch(char **cmdline_p)
235 sparc_cpu_model = sun4e; 235 sparc_cpu_model = sun4e;
236 if (!strcmp(&cputypval,"sun4u")) 236 if (!strcmp(&cputypval,"sun4u"))
237 sparc_cpu_model = sun4u; 237 sparc_cpu_model = sun4u;
238 if (!strncmp(&cputypval, "leon" , 4))
239 sparc_cpu_model = sparc_leon;
238 240
239 printk("ARCH: "); 241 printk("ARCH: ");
240 switch(sparc_cpu_model) { 242 switch(sparc_cpu_model) {
@@ -256,6 +258,9 @@ void __init setup_arch(char **cmdline_p)
256 case sun4u: 258 case sun4u:
257 printk("SUN4U\n"); 259 printk("SUN4U\n");
258 break; 260 break;
261 case sparc_leon:
262 printk("LEON\n");
263 break;
259 default: 264 default:
260 printk("UNKNOWN!\n"); 265 printk("UNKNOWN!\n");
261 break; 266 break;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 181d069a2d44..7ce1a1005b1d 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -590,6 +590,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
590 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 590 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
591 clear_thread_flag(TIF_NOTIFY_RESUME); 591 clear_thread_flag(TIF_NOTIFY_RESUME);
592 tracehook_notify_resume(regs); 592 tracehook_notify_resume(regs);
593 if (current->replacement_session_keyring)
594 key_replace_session_keyring();
593 } 595 }
594} 596}
595 597
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index ec82d76dc6f2..647afbda7ae1 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -613,5 +613,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
613 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 613 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
614 clear_thread_flag(TIF_NOTIFY_RESUME); 614 clear_thread_flag(TIF_NOTIFY_RESUME);
615 tracehook_notify_resume(regs); 615 tracehook_notify_resume(regs);
616 if (current->replacement_session_keyring)
617 key_replace_session_keyring();
616 } 618 }
617} 619}
620
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index aed94869ad6a..e7061138c98a 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -121,7 +121,7 @@ SIGN2(sys32_syslog, sys_syslog, %o0, %o2)
121SIGN1(sys32_umask, sys_umask, %o0) 121SIGN1(sys32_umask, sys_umask, %o0)
122SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2) 122SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2)
123SIGN1(sys32_sendto, sys_sendto, %o0) 123SIGN1(sys32_sendto, sys_sendto, %o0)
124SIGN1(sys32_recvfrom, sys_recvfrom, %o0) 124SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
125SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2) 125SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2)
126SIGN2(sys32_connect, sys_connect, %o0, %o2) 126SIGN2(sys32_connect, sys_connect, %o0, %o2)
127SIGN2(sys32_bind, sys_bind, %o0, %o2) 127SIGN2(sys32_bind, sys_bind, %o0, %o2)
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c
index d28f496f4669..ca39c606fe8e 100644
--- a/arch/sparc/kernel/sysfs.c
+++ b/arch/sparc/kernel/sysfs.c
@@ -2,6 +2,7 @@
2 * 2 *
3 * Copyright (C) 2007 David S. Miller <davem@davemloft.net> 3 * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
4 */ 4 */
5#include <linux/sched.h>
5#include <linux/sysdev.h> 6#include <linux/sysdev.h>
6#include <linux/cpu.h> 7#include <linux/cpu.h>
7#include <linux/smp.h> 8#include <linux/smp.h>
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 690901657291..04181577cb65 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -82,5 +82,5 @@ sys_call_table:
82/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate 82/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
83/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 83/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
84/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv 84/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
85/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo 85/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_counter_open
86 86
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 2ee7250ba7ae..91b06b7f7acf 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -83,7 +83,7 @@ sys_call_table32:
83/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate 83/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
84 .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 84 .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
85/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv 85/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
86 .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo 86 .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_counter_open
87 87
88#endif /* CONFIG_COMPAT */ 88#endif /* CONFIG_COMPAT */
89 89
@@ -158,4 +158,4 @@ sys_call_table:
158/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate 158/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
159 .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 159 .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
160/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv 160/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
161 .word sys_pwritev, sys_rt_tgsigqueueinfo 161 .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_counter_open
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 681abe0a4594..79836a7dd00c 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SPARC32) += loadmmu.o
11obj-y += generic_$(BITS).o 11obj-y += generic_$(BITS).o
12obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o 12obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o
13obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o 13obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o
14obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
14 15
15# Only used by sparc64 16# Only used by sparc64
16obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 17obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 26bb3919ff1f..54114ad0bdee 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -34,6 +34,7 @@
34#include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */ 34#include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */
35#include <asm/tlb.h> 35#include <asm/tlb.h>
36#include <asm/prom.h> 36#include <asm/prom.h>
37#include <asm/leon.h>
37 38
38DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 39DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
39 40
@@ -326,6 +327,9 @@ void __init paging_init(void)
326 sparc_unmapped_base = 0xe0000000; 327 sparc_unmapped_base = 0xe0000000;
327 BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000); 328 BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000);
328 break; 329 break;
330 case sparc_leon:
331 leon_init();
332 /* fall through */
329 case sun4m: 333 case sun4m:
330 case sun4d: 334 case sun4d:
331 srmmu_paging_init(); 335 srmmu_paging_init();
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c
new file mode 100644
index 000000000000..c0e01297e64e
--- /dev/null
+++ b/arch/sparc/mm/leon_mm.c
@@ -0,0 +1,260 @@
1/*
2 * linux/arch/sparc/mm/leon_m.c
3 *
4 * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de, konrad@gaisler.com) Gaisler Research
5 * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
6 * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
7 *
8 * do srmmu probe in software
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/mm.h>
14#include <asm/asi.h>
15#include <asm/leon.h>
16#include <asm/tlbflush.h>
17
18int leon_flush_during_switch = 1;
19int srmmu_swprobe_trace;
20
21unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr)
22{
23
24 unsigned int ctxtbl;
25 unsigned int pgd, pmd, ped;
26 unsigned int ptr;
27 unsigned int lvl, pte, paddrbase;
28 unsigned int ctx;
29 unsigned int paddr_calc;
30
31 paddrbase = 0;
32
33 if (srmmu_swprobe_trace)
34 printk(KERN_INFO "swprobe: trace on\n");
35
36 ctxtbl = srmmu_get_ctable_ptr();
37 if (!(ctxtbl)) {
38 if (srmmu_swprobe_trace)
39 printk(KERN_INFO "swprobe: srmmu_get_ctable_ptr returned 0=>0\n");
40 return 0;
41 }
42 if (!_pfn_valid(PFN(ctxtbl))) {
43 if (srmmu_swprobe_trace)
44 printk(KERN_INFO
45 "swprobe: !_pfn_valid(%x)=>0\n",
46 PFN(ctxtbl));
47 return 0;
48 }
49
50 ctx = srmmu_get_context();
51 if (srmmu_swprobe_trace)
52 printk(KERN_INFO "swprobe: --- ctx (%x) ---\n", ctx);
53
54 pgd = LEON_BYPASS_LOAD_PA(ctxtbl + (ctx * 4));
55
56 if (((pgd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
57 if (srmmu_swprobe_trace)
58 printk(KERN_INFO "swprobe: pgd is entry level 3\n");
59 lvl = 3;
60 pte = pgd;
61 paddrbase = pgd & _SRMMU_PTE_PMASK_LEON;
62 goto ready;
63 }
64 if (((pgd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
65 if (srmmu_swprobe_trace)
66 printk(KERN_INFO "swprobe: pgd is invalid => 0\n");
67 return 0;
68 }
69
70 if (srmmu_swprobe_trace)
71 printk(KERN_INFO "swprobe: --- pgd (%x) ---\n", pgd);
72
73 ptr = (pgd & SRMMU_PTD_PMASK) << 4;
74 ptr += ((((vaddr) >> LEON_PGD_SH) & LEON_PGD_M) * 4);
75 if (!_pfn_valid(PFN(ptr)))
76 return 0;
77
78 pmd = LEON_BYPASS_LOAD_PA(ptr);
79 if (((pmd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
80 if (srmmu_swprobe_trace)
81 printk(KERN_INFO "swprobe: pmd is entry level 2\n");
82 lvl = 2;
83 pte = pmd;
84 paddrbase = pmd & _SRMMU_PTE_PMASK_LEON;
85 goto ready;
86 }
87 if (((pmd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
88 if (srmmu_swprobe_trace)
89 printk(KERN_INFO "swprobe: pmd is invalid => 0\n");
90 return 0;
91 }
92
93 if (srmmu_swprobe_trace)
94 printk(KERN_INFO "swprobe: --- pmd (%x) ---\n", pmd);
95
96 ptr = (pmd & SRMMU_PTD_PMASK) << 4;
97 ptr += (((vaddr >> LEON_PMD_SH) & LEON_PMD_M) * 4);
98 if (!_pfn_valid(PFN(ptr))) {
99 if (srmmu_swprobe_trace)
100 printk(KERN_INFO "swprobe: !_pfn_valid(%x)=>0\n",
101 PFN(ptr));
102 return 0;
103 }
104
105 ped = LEON_BYPASS_LOAD_PA(ptr);
106
107 if (((ped & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
108 if (srmmu_swprobe_trace)
109 printk(KERN_INFO "swprobe: ped is entry level 1\n");
110 lvl = 1;
111 pte = ped;
112 paddrbase = ped & _SRMMU_PTE_PMASK_LEON;
113 goto ready;
114 }
115 if (((ped & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
116 if (srmmu_swprobe_trace)
117 printk(KERN_INFO "swprobe: ped is invalid => 0\n");
118 return 0;
119 }
120
121 if (srmmu_swprobe_trace)
122 printk(KERN_INFO "swprobe: --- ped (%x) ---\n", ped);
123
124 ptr = (ped & SRMMU_PTD_PMASK) << 4;
125 ptr += (((vaddr >> LEON_PTE_SH) & LEON_PTE_M) * 4);
126 if (!_pfn_valid(PFN(ptr)))
127 return 0;
128
129 ptr = LEON_BYPASS_LOAD_PA(ptr);
130 if (((ptr & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
131 if (srmmu_swprobe_trace)
132 printk(KERN_INFO "swprobe: ptr is entry level 0\n");
133 lvl = 0;
134 pte = ptr;
135 paddrbase = ptr & _SRMMU_PTE_PMASK_LEON;
136 goto ready;
137 }
138 if (srmmu_swprobe_trace)
139 printk(KERN_INFO "swprobe: ptr is invalid => 0\n");
140 return 0;
141
142ready:
143 switch (lvl) {
144 case 0:
145 paddr_calc =
146 (vaddr & ~(-1 << LEON_PTE_SH)) | ((pte & ~0xff) << 4);
147 break;
148 case 1:
149 paddr_calc =
150 (vaddr & ~(-1 << LEON_PMD_SH)) | ((pte & ~0xff) << 4);
151 break;
152 case 2:
153 paddr_calc =
154 (vaddr & ~(-1 << LEON_PGD_SH)) | ((pte & ~0xff) << 4);
155 break;
156 default:
157 case 3:
158 paddr_calc = vaddr;
159 break;
160 }
161 if (srmmu_swprobe_trace)
162 printk(KERN_INFO "swprobe: padde %x\n", paddr_calc);
163 if (paddr)
164 *paddr = paddr_calc;
165 return paddrbase;
166}
167
168void leon_flush_icache_all(void)
169{
170 __asm__ __volatile__(" flush "); /*iflush*/
171}
172
173void leon_flush_dcache_all(void)
174{
175 __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
176 "i"(ASI_LEON_DFLUSH) : "memory");
177}
178
179void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page)
180{
181 if (vma->vm_flags & VM_EXEC)
182 leon_flush_icache_all();
183 leon_flush_dcache_all();
184}
185
186void leon_flush_cache_all(void)
187{
188 __asm__ __volatile__(" flush "); /*iflush*/
189 __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
190 "i"(ASI_LEON_DFLUSH) : "memory");
191}
192
193void leon_flush_tlb_all(void)
194{
195 leon_flush_cache_all();
196 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : "r"(0x400),
197 "i"(ASI_LEON_MMUFLUSH) : "memory");
198}
199
200/* get all cache regs */
201void leon3_getCacheRegs(struct leon3_cacheregs *regs)
202{
203 unsigned long ccr, iccr, dccr;
204
205 if (!regs)
206 return;
207 /* Get Cache regs from "Cache ASI" address 0x0, 0x8 and 0xC */
208 __asm__ __volatile__("lda [%%g0] %3, %0\n\t"
209 "mov 0x08, %%g1\n\t"
210 "lda [%%g1] %3, %1\n\t"
211 "mov 0x0c, %%g1\n\t"
212 "lda [%%g1] %3, %2\n\t"
213 : "=r"(ccr), "=r"(iccr), "=r"(dccr)
214 /* output */
215 : "i"(ASI_LEON_CACHEREGS) /* input */
216 : "g1" /* clobber list */
217 );
218 regs->ccr = ccr;
219 regs->iccr = iccr;
220 regs->dccr = dccr;
221}
222
223/* Due to virtual cache we need to check cache configuration if
224 * it is possible to skip flushing in some cases.
225 *
226 * Leon2 and Leon3 differ in their way of telling cache information
227 *
228 */
229int leon_flush_needed(void)
230{
231 int flush_needed = -1;
232 unsigned int ssize, sets;
233 char *setStr[4] =
234 { "direct mapped", "2-way associative", "3-way associative",
235 "4-way associative"
236 };
237 /* leon 3 */
238 struct leon3_cacheregs cregs;
239 leon3_getCacheRegs(&cregs);
240 sets = (cregs.dccr & LEON3_XCCR_SETS_MASK) >> 24;
241 /* (ssize=>realsize) 0=>1k, 1=>2k, 2=>4k, 3=>8k ... */
242 ssize = 1 << ((cregs.dccr & LEON3_XCCR_SSIZE_MASK) >> 20);
243
244 printk(KERN_INFO "CACHE: %s cache, set size %dk\n",
245 sets > 3 ? "unknown" : setStr[sets], ssize);
246 if ((ssize <= (PAGE_SIZE / 1024)) && (sets == 0)) {
247 /* Set Size <= Page size ==>
248 flush on every context switch not needed. */
249 flush_needed = 0;
250 printk(KERN_INFO "CACHE: not flushing on every context switch\n");
251 }
252 return flush_needed;
253}
254
255void leon_switch_mm(void)
256{
257 flush_tlb_mm((void *)0);
258 if (leon_flush_during_switch)
259 leon_flush_cache_all();
260}
diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c
index 652be05acbea..82ec8f666036 100644
--- a/arch/sparc/mm/loadmmu.c
+++ b/arch/sparc/mm/loadmmu.c
@@ -33,6 +33,7 @@ void __init load_mmu(void)
33 break; 33 break;
34 case sun4m: 34 case sun4m:
35 case sun4d: 35 case sun4d:
36 case sparc_leon:
36 ld_mmu_srmmu(); 37 ld_mmu_srmmu();
37 break; 38 break;
38 default: 39 default:
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index ade4eb373bdd..509b1ffeba66 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -46,6 +46,7 @@
46#include <asm/tsunami.h> 46#include <asm/tsunami.h>
47#include <asm/swift.h> 47#include <asm/swift.h>
48#include <asm/turbosparc.h> 48#include <asm/turbosparc.h>
49#include <asm/leon.h>
49 50
50#include <asm/btfixup.h> 51#include <asm/btfixup.h>
51 52
@@ -569,6 +570,9 @@ static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
569 srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd); 570 srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
570 } 571 }
571 572
573 if (sparc_cpu_model == sparc_leon)
574 leon_switch_mm();
575
572 if (is_hypersparc) 576 if (is_hypersparc)
573 hyper_flush_whole_icache(); 577 hyper_flush_whole_icache();
574 578
@@ -1977,6 +1981,45 @@ static void __init init_viking(void)
1977 poke_srmmu = poke_viking; 1981 poke_srmmu = poke_viking;
1978} 1982}
1979 1983
1984#ifdef CONFIG_SPARC_LEON
1985
1986void __init poke_leonsparc(void)
1987{
1988}
1989
1990void __init init_leon(void)
1991{
1992
1993 srmmu_name = "Leon";
1994
1995 BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all,
1996 BTFIXUPCALL_NORM);
1997 BTFIXUPSET_CALL(flush_cache_mm, leon_flush_cache_all,
1998 BTFIXUPCALL_NORM);
1999 BTFIXUPSET_CALL(flush_cache_page, leon_flush_pcache_all,
2000 BTFIXUPCALL_NORM);
2001 BTFIXUPSET_CALL(flush_cache_range, leon_flush_cache_all,
2002 BTFIXUPCALL_NORM);
2003 BTFIXUPSET_CALL(flush_page_for_dma, leon_flush_dcache_all,
2004 BTFIXUPCALL_NORM);
2005
2006 BTFIXUPSET_CALL(flush_tlb_all, leon_flush_tlb_all, BTFIXUPCALL_NORM);
2007 BTFIXUPSET_CALL(flush_tlb_mm, leon_flush_tlb_all, BTFIXUPCALL_NORM);
2008 BTFIXUPSET_CALL(flush_tlb_page, leon_flush_tlb_all, BTFIXUPCALL_NORM);
2009 BTFIXUPSET_CALL(flush_tlb_range, leon_flush_tlb_all, BTFIXUPCALL_NORM);
2010
2011 BTFIXUPSET_CALL(__flush_page_to_ram, leon_flush_cache_all,
2012 BTFIXUPCALL_NOP);
2013 BTFIXUPSET_CALL(flush_sig_insns, leon_flush_cache_all, BTFIXUPCALL_NOP);
2014
2015 poke_srmmu = poke_leonsparc;
2016
2017 srmmu_cache_pagetables = 0;
2018
2019 leon_flush_during_switch = leon_flush_needed();
2020}
2021#endif
2022
1980/* Probe for the srmmu chip version. */ 2023/* Probe for the srmmu chip version. */
1981static void __init get_srmmu_type(void) 2024static void __init get_srmmu_type(void)
1982{ 2025{
@@ -1992,7 +2035,15 @@ static void __init get_srmmu_type(void)
1992 psr_typ = (psr >> 28) & 0xf; 2035 psr_typ = (psr >> 28) & 0xf;
1993 psr_vers = (psr >> 24) & 0xf; 2036 psr_vers = (psr >> 24) & 0xf;
1994 2037
1995 /* First, check for HyperSparc or Cypress. */ 2038 /* First, check for sparc-leon. */
2039 if (sparc_cpu_model == sparc_leon) {
2040 psr_typ = 0xf; /* hardcoded ids for older models/simulators */
2041 psr_vers = 2;
2042 init_leon();
2043 return;
2044 }
2045
2046 /* Second, check for HyperSparc or Cypress. */
1996 if(mod_typ == 1) { 2047 if(mod_typ == 1) {
1997 switch(mod_rev) { 2048 switch(mod_rev) {
1998 case 7: 2049 case 7:
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c
index d172f86439b1..f97cb8b6ee5f 100644
--- a/arch/sparc/oprofile/init.c
+++ b/arch/sparc/oprofile/init.c
@@ -21,7 +21,7 @@
21static int profile_timer_exceptions_notify(struct notifier_block *self, 21static int profile_timer_exceptions_notify(struct notifier_block *self,
22 unsigned long val, void *data) 22 unsigned long val, void *data)
23{ 23{
24 struct die_args *args = (struct die_args *)data; 24 struct die_args *args = data;
25 int ret = NOTIFY_DONE; 25 int ret = NOTIFY_DONE;
26 26
27 switch (val) { 27 switch (val) {
@@ -57,7 +57,7 @@ static void timer_stop(void)
57 57
58static int op_nmi_timer_init(struct oprofile_operations *ops) 58static int op_nmi_timer_init(struct oprofile_operations *ops)
59{ 59{
60 if (!nmi_usable) 60 if (atomic_read(&nmi_active) <= 0)
61 return -ENODEV; 61 return -ENODEV;
62 62
63 ops->start = timer_start; 63 ops->start = timer_start;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 3b44b47c7e1d..f114813ae258 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -245,7 +245,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
245 245
246 dev_kfree_skb(skb); 246 dev_kfree_skb(skb);
247 247
248 return 0; 248 return NETDEV_TX_OK;
249} 249}
250 250
251static void uml_net_set_multicast_list(struct net_device *dev) 251static void uml_net_set_multicast_list(struct net_device *dev)
@@ -285,7 +285,7 @@ static void uml_net_get_drvinfo(struct net_device *dev,
285 strcpy(info->version, "42"); 285 strcpy(info->version, "42");
286} 286}
287 287
288static struct ethtool_ops uml_net_ethtool_ops = { 288static const struct ethtool_ops uml_net_ethtool_ops = {
289 .get_drvinfo = uml_net_get_drvinfo, 289 .get_drvinfo = uml_net_get_drvinfo,
290 .get_link = ethtool_op_get_link, 290 .get_link = ethtool_op_get_link,
291}; 291};
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f46f30d23eb0..c71a8f8bdba8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -587,7 +587,6 @@ config GART_IOMMU
587 bool "GART IOMMU support" if EMBEDDED 587 bool "GART IOMMU support" if EMBEDDED
588 default y 588 default y
589 select SWIOTLB 589 select SWIOTLB
590 select AGP
591 depends on X86_64 && PCI 590 depends on X86_64 && PCI
592 ---help--- 591 ---help---
593 Support for full DMA access of devices with 32bit memory access only 592 Support for full DMA access of devices with 32bit memory access only
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 8130334329c0..527519b8a9f9 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -262,6 +262,15 @@ config MCORE2
262 family in /proc/cpuinfo. Newer ones have 6 and older ones 15 262 family in /proc/cpuinfo. Newer ones have 6 and older ones 15
263 (not a typo) 263 (not a typo)
264 264
265config MATOM
266 bool "Intel Atom"
267 ---help---
268
269 Select this for the Intel Atom platform. Intel Atom CPUs have an
270 in-order pipelining architecture and thus can benefit from
271 accordingly optimized code. Use a recent GCC with specific Atom
272 support in order to fully benefit from selecting this option.
273
265config GENERIC_CPU 274config GENERIC_CPU
266 bool "Generic-x86-64" 275 bool "Generic-x86-64"
267 depends on X86_64 276 depends on X86_64
@@ -295,7 +304,7 @@ config X86_CPU
295config X86_L1_CACHE_BYTES 304config X86_L1_CACHE_BYTES
296 int 305 int
297 default "128" if MPSC 306 default "128" if MPSC
298 default "64" if GENERIC_CPU || MK8 || MCORE2 || X86_32 307 default "64" if GENERIC_CPU || MK8 || MCORE2 || MATOM || X86_32
299 308
300config X86_INTERNODE_CACHE_BYTES 309config X86_INTERNODE_CACHE_BYTES
301 int 310 int
@@ -310,7 +319,7 @@ config X86_L1_CACHE_SHIFT
310 default "7" if MPENTIUM4 || MPSC 319 default "7" if MPENTIUM4 || MPSC
311 default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 320 default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
312 default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX 321 default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
313 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 || X86_GENERIC || GENERIC_CPU 322 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
314 323
315config X86_XADD 324config X86_XADD
316 def_bool y 325 def_bool y
@@ -359,7 +368,7 @@ config X86_INTEL_USERCOPY
359 368
360config X86_USE_PPRO_CHECKSUM 369config X86_USE_PPRO_CHECKSUM
361 def_bool y 370 def_bool y
362 depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 371 depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
363 372
364config X86_USE_3DNOW 373config X86_USE_3DNOW
365 def_bool y 374 def_bool y
@@ -387,7 +396,7 @@ config X86_P6_NOP
387 396
388config X86_TSC 397config X86_TSC
389 def_bool y 398 def_bool y
390 depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 399 depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64
391 400
392config X86_CMPXCHG64 401config X86_CMPXCHG64
393 def_bool y 402 def_bool y
@@ -397,7 +406,7 @@ config X86_CMPXCHG64
397# generates cmov. 406# generates cmov.
398config X86_CMOV 407config X86_CMOV
399 def_bool y 408 def_bool y
400 depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64) 409 depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM)
401 410
402config X86_MINIMUM_CPU_FAMILY 411config X86_MINIMUM_CPU_FAMILY
403 int 412 int
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 1b68659c41b4..7983c420eaf2 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -32,8 +32,8 @@ ifeq ($(CONFIG_X86_32),y)
32 32
33 # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use 33 # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
34 # a lot more stack due to the lack of sharing of stacklots: 34 # a lot more stack due to the lack of sharing of stacklots:
35 KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ 35 KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0400, \
36 echo $(call cc-option,-fno-unit-at-a-time); fi ;) 36 $(call cc-option,-fno-unit-at-a-time))
37 37
38 # CPU-specific tuning. Anything which can be shared with UML should go here. 38 # CPU-specific tuning. Anything which can be shared with UML should go here.
39 include $(srctree)/arch/x86/Makefile_32.cpu 39 include $(srctree)/arch/x86/Makefile_32.cpu
@@ -55,6 +55,8 @@ else
55 55
56 cflags-$(CONFIG_MCORE2) += \ 56 cflags-$(CONFIG_MCORE2) += \
57 $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) 57 $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
58 cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
59 $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
58 cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) 60 cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
59 KBUILD_CFLAGS += $(cflags-y) 61 KBUILD_CFLAGS += $(cflags-y)
60 62
@@ -72,7 +74,7 @@ endif
72 74
73ifdef CONFIG_CC_STACKPROTECTOR 75ifdef CONFIG_CC_STACKPROTECTOR
74 cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh 76 cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
75 ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC)),y) 77 ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y)
76 stackp-y := -fstack-protector 78 stackp-y := -fstack-protector
77 stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all 79 stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all
78 KBUILD_CFLAGS += $(stackp-y) 80 KBUILD_CFLAGS += $(stackp-y)
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 80177ec052f0..30e9a264f69d 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -33,6 +33,8 @@ cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-f
33cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) 33cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
34cflags-$(CONFIG_MVIAC7) += -march=i686 34cflags-$(CONFIG_MVIAC7) += -march=i686
35cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) 35cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2)
36cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \
37 $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
36 38
37# AMD Elan support 39# AMD Elan support
38cflags-$(CONFIG_X86_ELAN) += -march=i486 40cflags-$(CONFIG_X86_ELAN) += -march=i486
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 275dd177f198..11e8c6eb80a1 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -31,7 +31,6 @@ static inline void vesa_store_mode_params_graphics(void) {}
31 31
32static int vesa_probe(void) 32static int vesa_probe(void)
33{ 33{
34#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
35 struct biosregs ireg, oreg; 34 struct biosregs ireg, oreg;
36 u16 mode; 35 u16 mode;
37 addr_t mode_ptr; 36 addr_t mode_ptr;
@@ -49,8 +48,7 @@ static int vesa_probe(void)
49 vginfo.signature != VESA_MAGIC || 48 vginfo.signature != VESA_MAGIC ||
50 vginfo.version < 0x0102) 49 vginfo.version < 0x0102)
51 return 0; /* Not present */ 50 return 0; /* Not present */
52#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */ 51
53#ifdef CONFIG_VIDEO_VESA
54 set_fs(vginfo.video_mode_ptr.seg); 52 set_fs(vginfo.video_mode_ptr.seg);
55 mode_ptr = vginfo.video_mode_ptr.off; 53 mode_ptr = vginfo.video_mode_ptr.off;
56 54
@@ -102,9 +100,6 @@ static int vesa_probe(void)
102 } 100 }
103 101
104 return nmodes; 102 return nmodes;
105#else
106 return 0;
107#endif /* CONFIG_VIDEO_VESA */
108} 103}
109 104
110static int vesa_set_mode(struct mode_info *mode) 105static int vesa_set_mode(struct mode_info *mode)
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 8f8d827e254d..819caa1f2008 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -47,14 +47,6 @@ static u8 vga_set_basic_mode(void)
47 47
48 initregs(&ireg); 48 initregs(&ireg);
49 49
50#ifdef CONFIG_VIDEO_400_HACK
51 if (adapter >= ADAPTER_VGA) {
52 ireg.ax = 0x1202;
53 ireg.bx = 0x0030;
54 intcall(0x10, &ireg, NULL);
55 }
56#endif
57
58 ax = 0x0f00; 50 ax = 0x0f00;
59 intcall(0x10, &ireg, &oreg); 51 intcall(0x10, &ireg, &oreg);
60 mode = oreg.al; 52 mode = oreg.al;
@@ -62,11 +54,9 @@ static u8 vga_set_basic_mode(void)
62 set_fs(0); 54 set_fs(0);
63 rows = rdfs8(0x484); /* rows minus one */ 55 rows = rdfs8(0x484); /* rows minus one */
64 56
65#ifndef CONFIG_VIDEO_400_HACK
66 if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) && 57 if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) &&
67 (rows == 0 || rows == 24)) 58 (rows == 0 || rows == 24))
68 return mode; 59 return mode;
69#endif
70 60
71 if (mode != 3 && mode != 7) 61 if (mode != 3 && mode != 7)
72 mode = 3; 62 mode = 3;
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index bad728b76fc2..d42da3802499 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -221,7 +221,6 @@ static unsigned int mode_menu(void)
221 } 221 }
222} 222}
223 223
224#ifdef CONFIG_VIDEO_RETAIN
225/* Save screen content to the heap */ 224/* Save screen content to the heap */
226static struct saved_screen { 225static struct saved_screen {
227 int x, y; 226 int x, y;
@@ -299,10 +298,6 @@ static void restore_screen(void)
299 ireg.dl = saved.curx; 298 ireg.dl = saved.curx;
300 intcall(0x10, &ireg, NULL); 299 intcall(0x10, &ireg, NULL);
301} 300}
302#else
303#define save_screen() ((void)0)
304#define restore_screen() ((void)0)
305#endif
306 301
307void set_video(void) 302void set_video(void)
308{ 303{
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h
index 5bb174a997fc..ff339c5db311 100644
--- a/arch/x86/boot/video.h
+++ b/arch/x86/boot/video.h
@@ -17,19 +17,8 @@
17 17
18#include <linux/types.h> 18#include <linux/types.h>
19 19
20/* Enable autodetection of SVGA adapters and modes. */ 20/*
21#undef CONFIG_VIDEO_SVGA 21 * This code uses an extended set of video mode numbers. These include:
22
23/* Enable autodetection of VESA modes */
24#define CONFIG_VIDEO_VESA
25
26/* Retain screen contents when switching modes */
27#define CONFIG_VIDEO_RETAIN
28
29/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
30#undef CONFIG_VIDEO_400_HACK
31
32/* This code uses an extended set of video mode numbers. These include:
33 * Aliases for standard modes 22 * Aliases for standard modes
34 * NORMAL_VGA (-1) 23 * NORMAL_VGA (-1)
35 * EXTENDED_VGA (-2) 24 * EXTENDED_VGA (-2)
@@ -67,13 +56,8 @@
67/* The "recalculate timings" flag */ 56/* The "recalculate timings" flag */
68#define VIDEO_RECALC 0x8000 57#define VIDEO_RECALC 0x8000
69 58
70/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
71#ifdef CONFIG_VIDEO_RETAIN
72void store_screen(void); 59void store_screen(void);
73#define DO_STORE() store_screen() 60#define DO_STORE() store_screen()
74#else
75#define DO_STORE() ((void)0)
76#endif /* CONFIG_VIDEO_RETAIN */
77 61
78/* 62/*
79 * Mode table structures 63 * Mode table structures
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index c580c5ec1cad..585edebe12cf 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -59,13 +59,6 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out,
59asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, 59asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
60 const u8 *in, unsigned int len, u8 *iv); 60 const u8 *in, unsigned int len, u8 *iv);
61 61
62static inline int kernel_fpu_using(void)
63{
64 if (in_interrupt() && !(read_cr0() & X86_CR0_TS))
65 return 1;
66 return 0;
67}
68
69static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) 62static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
70{ 63{
71 unsigned long addr = (unsigned long)raw_ctx; 64 unsigned long addr = (unsigned long)raw_ctx;
@@ -89,7 +82,7 @@ static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx,
89 return -EINVAL; 82 return -EINVAL;
90 } 83 }
91 84
92 if (kernel_fpu_using()) 85 if (irq_fpu_usable())
93 err = crypto_aes_expand_key(ctx, in_key, key_len); 86 err = crypto_aes_expand_key(ctx, in_key, key_len);
94 else { 87 else {
95 kernel_fpu_begin(); 88 kernel_fpu_begin();
@@ -110,7 +103,7 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
110{ 103{
111 struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm)); 104 struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
112 105
113 if (kernel_fpu_using()) 106 if (irq_fpu_usable())
114 crypto_aes_encrypt_x86(ctx, dst, src); 107 crypto_aes_encrypt_x86(ctx, dst, src);
115 else { 108 else {
116 kernel_fpu_begin(); 109 kernel_fpu_begin();
@@ -123,7 +116,7 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
123{ 116{
124 struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm)); 117 struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
125 118
126 if (kernel_fpu_using()) 119 if (irq_fpu_usable())
127 crypto_aes_decrypt_x86(ctx, dst, src); 120 crypto_aes_decrypt_x86(ctx, dst, src);
128 else { 121 else {
129 kernel_fpu_begin(); 122 kernel_fpu_begin();
@@ -349,7 +342,7 @@ static int ablk_encrypt(struct ablkcipher_request *req)
349 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 342 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
350 struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); 343 struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
351 344
352 if (kernel_fpu_using()) { 345 if (irq_fpu_usable()) {
353 struct ablkcipher_request *cryptd_req = 346 struct ablkcipher_request *cryptd_req =
354 ablkcipher_request_ctx(req); 347 ablkcipher_request_ctx(req);
355 memcpy(cryptd_req, req, sizeof(*req)); 348 memcpy(cryptd_req, req, sizeof(*req));
@@ -370,7 +363,7 @@ static int ablk_decrypt(struct ablkcipher_request *req)
370 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 363 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
371 struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); 364 struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
372 365
373 if (kernel_fpu_using()) { 366 if (irq_fpu_usable()) {
374 struct ablkcipher_request *cryptd_req = 367 struct ablkcipher_request *cryptd_req =
375 ablkcipher_request_ctx(req); 368 ablkcipher_request_ctx(req);
376 memcpy(cryptd_req, req, sizeof(*req)); 369 memcpy(cryptd_req, req, sizeof(*req));
@@ -636,7 +629,7 @@ static int __init aesni_init(void)
636 int err; 629 int err;
637 630
638 if (!cpu_has_aes) { 631 if (!cpu_has_aes) {
639 printk(KERN_ERR "Intel AES-NI instructions are not detected.\n"); 632 printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
640 return -ENODEV; 633 return -ENODEV;
641 } 634 }
642 if ((err = crypto_register_alg(&aesni_alg))) 635 if ((err = crypto_register_alg(&aesni_alg)))
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index e590261ba059..ba331bfd1112 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -537,7 +537,7 @@ ia32_sys_call_table:
537 .quad sys_mkdir 537 .quad sys_mkdir
538 .quad sys_rmdir /* 40 */ 538 .quad sys_rmdir /* 40 */
539 .quad sys_dup 539 .quad sys_dup
540 .quad sys32_pipe 540 .quad sys_pipe
541 .quad compat_sys_times 541 .quad compat_sys_times
542 .quad quiet_ni_syscall /* old prof syscall holder */ 542 .quad quiet_ni_syscall /* old prof syscall holder */
543 .quad sys_brk /* 45 */ 543 .quad sys_brk /* 45 */
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 085a8c35f149..9f5527198825 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -189,20 +189,6 @@ asmlinkage long sys32_mprotect(unsigned long start, size_t len,
189 return sys_mprotect(start, len, prot); 189 return sys_mprotect(start, len, prot);
190} 190}
191 191
192asmlinkage long sys32_pipe(int __user *fd)
193{
194 int retval;
195 int fds[2];
196
197 retval = do_pipe_flags(fds, 0);
198 if (retval)
199 goto out;
200 if (copy_to_user(fd, fds, sizeof(fds)))
201 retval = -EFAULT;
202out:
203 return retval;
204}
205
206asmlinkage long sys32_rt_sigaction(int sig, struct sigaction32 __user *act, 192asmlinkage long sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
207 struct sigaction32 __user *oact, 193 struct sigaction32 __user *oact,
208 unsigned int sigsetsize) 194 unsigned int sigsetsize)
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 1a37bcdc8606..c240efc74e00 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -73,8 +73,6 @@ static inline void alternatives_smp_module_del(struct module *mod) {}
73static inline void alternatives_smp_switch(int smp) {} 73static inline void alternatives_smp_switch(int smp) {}
74#endif /* CONFIG_SMP */ 74#endif /* CONFIG_SMP */
75 75
76const unsigned char *const *find_nop_table(void);
77
78/* alternative assembly primitive: */ 76/* alternative assembly primitive: */
79#define ALTERNATIVE(oldinstr, newinstr, feature) \ 77#define ALTERNATIVE(oldinstr, newinstr, feature) \
80 \ 78 \
@@ -144,8 +142,6 @@ static inline void apply_paravirt(struct paravirt_patch_site *start,
144#define __parainstructions_end NULL 142#define __parainstructions_end NULL
145#endif 143#endif
146 144
147extern void add_nops(void *insns, unsigned int len);
148
149/* 145/*
150 * Clear and restore the kernel write-protection flag on the local CPU. 146 * Clear and restore the kernel write-protection flag on the local CPU.
151 * Allows the kernel to edit read-only pages. 147 * Allows the kernel to edit read-only pages.
@@ -161,10 +157,7 @@ extern void add_nops(void *insns, unsigned int len);
161 * Intel's errata. 157 * Intel's errata.
162 * On the local CPU you need to be protected again NMI or MCE handlers seeing an 158 * On the local CPU you need to be protected again NMI or MCE handlers seeing an
163 * inconsistent instruction while you patch. 159 * inconsistent instruction while you patch.
164 * The _early version expects the memory to already be RW.
165 */ 160 */
166
167extern void *text_poke(void *addr, const void *opcode, size_t len); 161extern void *text_poke(void *addr, const void *opcode, size_t len);
168extern void *text_poke_early(void *addr, const void *opcode, size_t len);
169 162
170#endif /* _ASM_X86_ALTERNATIVE_H */ 163#endif /* _ASM_X86_ALTERNATIVE_H */
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
index bdf96f119f06..ac95995b7bad 100644
--- a/arch/x86/include/asm/amd_iommu.h
+++ b/arch/x86/include/asm/amd_iommu.h
@@ -25,6 +25,7 @@
25#ifdef CONFIG_AMD_IOMMU 25#ifdef CONFIG_AMD_IOMMU
26extern int amd_iommu_init(void); 26extern int amd_iommu_init(void);
27extern int amd_iommu_init_dma_ops(void); 27extern int amd_iommu_init_dma_ops(void);
28extern int amd_iommu_init_passthrough(void);
28extern void amd_iommu_detect(void); 29extern void amd_iommu_detect(void);
29extern irqreturn_t amd_iommu_int_handler(int irq, void *data); 30extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
30extern void amd_iommu_flush_all_domains(void); 31extern void amd_iommu_flush_all_domains(void);
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index 0c878caaa0a2..2a2cc7a78a81 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -143,22 +143,29 @@
143#define EVT_BUFFER_SIZE 8192 /* 512 entries */ 143#define EVT_BUFFER_SIZE 8192 /* 512 entries */
144#define EVT_LEN_MASK (0x9ULL << 56) 144#define EVT_LEN_MASK (0x9ULL << 56)
145 145
146#define PAGE_MODE_NONE 0x00
146#define PAGE_MODE_1_LEVEL 0x01 147#define PAGE_MODE_1_LEVEL 0x01
147#define PAGE_MODE_2_LEVEL 0x02 148#define PAGE_MODE_2_LEVEL 0x02
148#define PAGE_MODE_3_LEVEL 0x03 149#define PAGE_MODE_3_LEVEL 0x03
149 150#define PAGE_MODE_4_LEVEL 0x04
150#define IOMMU_PDE_NL_0 0x000ULL 151#define PAGE_MODE_5_LEVEL 0x05
151#define IOMMU_PDE_NL_1 0x200ULL 152#define PAGE_MODE_6_LEVEL 0x06
152#define IOMMU_PDE_NL_2 0x400ULL 153
153#define IOMMU_PDE_NL_3 0x600ULL 154#define PM_LEVEL_SHIFT(x) (12 + ((x) * 9))
154 155#define PM_LEVEL_SIZE(x) (((x) < 6) ? \
155#define IOMMU_PTE_L2_INDEX(address) (((address) >> 30) & 0x1ffULL) 156 ((1ULL << PM_LEVEL_SHIFT((x))) - 1): \
156#define IOMMU_PTE_L1_INDEX(address) (((address) >> 21) & 0x1ffULL) 157 (0xffffffffffffffffULL))
157#define IOMMU_PTE_L0_INDEX(address) (((address) >> 12) & 0x1ffULL) 158#define PM_LEVEL_INDEX(x, a) (((a) >> PM_LEVEL_SHIFT((x))) & 0x1ffULL)
158 159#define PM_LEVEL_ENC(x) (((x) << 9) & 0xe00ULL)
159#define IOMMU_MAP_SIZE_L1 (1ULL << 21) 160#define PM_LEVEL_PDE(x, a) ((a) | PM_LEVEL_ENC((x)) | \
160#define IOMMU_MAP_SIZE_L2 (1ULL << 30) 161 IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW)
161#define IOMMU_MAP_SIZE_L3 (1ULL << 39) 162#define PM_PTE_LEVEL(pte) (((pte) >> 9) & 0x7ULL)
163
164#define PM_MAP_4k 0
165#define PM_ADDR_MASK 0x000ffffffffff000ULL
166#define PM_MAP_MASK(lvl) (PM_ADDR_MASK & \
167 (~((1ULL << (12 + ((lvl) * 9))) - 1)))
168#define PM_ALIGNED(lvl, addr) ((PM_MAP_MASK(lvl) & (addr)) == (addr))
162 169
163#define IOMMU_PTE_P (1ULL << 0) 170#define IOMMU_PTE_P (1ULL << 0)
164#define IOMMU_PTE_TV (1ULL << 1) 171#define IOMMU_PTE_TV (1ULL << 1)
@@ -167,11 +174,6 @@
167#define IOMMU_PTE_IR (1ULL << 61) 174#define IOMMU_PTE_IR (1ULL << 61)
168#define IOMMU_PTE_IW (1ULL << 62) 175#define IOMMU_PTE_IW (1ULL << 62)
169 176
170#define IOMMU_L1_PDE(address) \
171 ((address) | IOMMU_PDE_NL_1 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW)
172#define IOMMU_L2_PDE(address) \
173 ((address) | IOMMU_PDE_NL_2 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW)
174
175#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL) 177#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)
176#define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P) 178#define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P)
177#define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK)) 179#define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK))
@@ -194,11 +196,14 @@
194#define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ 196#define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */
195#define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops 197#define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops
196 domain for an IOMMU */ 198 domain for an IOMMU */
199#define PD_PASSTHROUGH_MASK (1UL << 2) /* domain has no page
200 translation */
201
197extern bool amd_iommu_dump; 202extern bool amd_iommu_dump;
198#define DUMP_printk(format, arg...) \ 203#define DUMP_printk(format, arg...) \
199 do { \ 204 do { \
200 if (amd_iommu_dump) \ 205 if (amd_iommu_dump) \
201 printk(KERN_INFO "AMD IOMMU: " format, ## arg); \ 206 printk(KERN_INFO "AMD-Vi: " format, ## arg); \
202 } while(0); 207 } while(0);
203 208
204/* 209/*
@@ -226,6 +231,7 @@ struct protection_domain {
226 int mode; /* paging mode (0-6 levels) */ 231 int mode; /* paging mode (0-6 levels) */
227 u64 *pt_root; /* page table root pointer */ 232 u64 *pt_root; /* page table root pointer */
228 unsigned long flags; /* flags to find out type of domain */ 233 unsigned long flags; /* flags to find out type of domain */
234 bool updated; /* complete domain flush required */
229 unsigned dev_cnt; /* devices assigned to this domain */ 235 unsigned dev_cnt; /* devices assigned to this domain */
230 void *priv; /* private data */ 236 void *priv; /* private data */
231}; 237};
@@ -337,6 +343,9 @@ struct amd_iommu {
337 /* if one, we need to send a completion wait command */ 343 /* if one, we need to send a completion wait command */
338 bool need_sync; 344 bool need_sync;
339 345
346 /* becomes true if a command buffer reset is running */
347 bool reset_in_progress;
348
340 /* default dma_ops domain for that IOMMU */ 349 /* default dma_ops domain for that IOMMU */
341 struct dma_ops_domain *default_dom; 350 struct dma_ops_domain *default_dom;
342}; 351};
@@ -457,4 +466,7 @@ static inline void amd_iommu_stats_init(void) { }
457 466
458#endif /* CONFIG_AMD_IOMMU_STATS */ 467#endif /* CONFIG_AMD_IOMMU_STATS */
459 468
469/* some function prototypes */
470extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
471
460#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ 472#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index bb7d47925847..586b7adb8e53 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -183,6 +183,10 @@ static inline int x2apic_enabled(void)
183} 183}
184 184
185#define x2apic_supported() (cpu_has_x2apic) 185#define x2apic_supported() (cpu_has_x2apic)
186static inline void x2apic_force_phys(void)
187{
188 x2apic_phys = 1;
189}
186#else 190#else
187static inline void check_x2apic(void) 191static inline void check_x2apic(void)
188{ 192{
@@ -194,6 +198,9 @@ static inline int x2apic_enabled(void)
194{ 198{
195 return 0; 199 return 0;
196} 200}
201static inline void x2apic_force_phys(void)
202{
203}
197 204
198#define x2apic_preenabled 0 205#define x2apic_preenabled 0
199#define x2apic_supported() 0 206#define x2apic_supported() 0
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 7ddb36ab933b..3b62da926de9 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -8,12 +8,14 @@
8 * Ingo Molnar <mingo@redhat.com>, 1999, 2000 8 * Ingo Molnar <mingo@redhat.com>, 1999, 2000
9 */ 9 */
10 10
11#define APIC_DEFAULT_PHYS_BASE 0xfee00000 11#define IO_APIC_DEFAULT_PHYS_BASE 0xfec00000
12#define APIC_DEFAULT_PHYS_BASE 0xfee00000
12 13
13#define APIC_ID 0x20 14#define APIC_ID 0x20
14 15
15#define APIC_LVR 0x30 16#define APIC_LVR 0x30
16#define APIC_LVR_MASK 0xFF00FF 17#define APIC_LVR_MASK 0xFF00FF
18#define APIC_LVR_DIRECTED_EOI (1 << 24)
17#define GET_APIC_VERSION(x) ((x) & 0xFFu) 19#define GET_APIC_VERSION(x) ((x) & 0xFFu)
18#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu) 20#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu)
19#ifdef CONFIG_X86_32 21#ifdef CONFIG_X86_32
@@ -40,6 +42,7 @@
40#define APIC_DFR_CLUSTER 0x0FFFFFFFul 42#define APIC_DFR_CLUSTER 0x0FFFFFFFul
41#define APIC_DFR_FLAT 0xFFFFFFFFul 43#define APIC_DFR_FLAT 0xFFFFFFFFul
42#define APIC_SPIV 0xF0 44#define APIC_SPIV 0xF0
45#define APIC_SPIV_DIRECTED_EOI (1 << 12)
43#define APIC_SPIV_FOCUS_DISABLED (1 << 9) 46#define APIC_SPIV_FOCUS_DISABLED (1 << 9)
44#define APIC_SPIV_APIC_ENABLED (1 << 8) 47#define APIC_SPIV_APIC_ENABLED (1 << 8)
45#define APIC_ISR 0x100 48#define APIC_ISR 0x100
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 56be78f582f0..b3ed1e1460ff 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -3,7 +3,7 @@
3 3
4#ifdef __ASSEMBLY__ 4#ifdef __ASSEMBLY__
5# define __ASM_FORM(x) x 5# define __ASM_FORM(x) x
6# define __ASM_EX_SEC .section __ex_table 6# define __ASM_EX_SEC .section __ex_table, "a"
7#else 7#else
8# define __ASM_FORM(x) " " #x " " 8# define __ASM_FORM(x) " " #x " "
9# define __ASM_EX_SEC " .section __ex_table,\"a\"\n" 9# define __ASM_EX_SEC " .section __ex_table,\"a\"\n"
@@ -38,10 +38,18 @@
38#define _ASM_DI __ASM_REG(di) 38#define _ASM_DI __ASM_REG(di)
39 39
40/* Exception table entry */ 40/* Exception table entry */
41#ifdef __ASSEMBLY__
42# define _ASM_EXTABLE(from,to) \
43 __ASM_EX_SEC ; \
44 _ASM_ALIGN ; \
45 _ASM_PTR from , to ; \
46 .previous
47#else
41# define _ASM_EXTABLE(from,to) \ 48# define _ASM_EXTABLE(from,to) \
42 __ASM_EX_SEC \ 49 __ASM_EX_SEC \
43 _ASM_ALIGN "\n" \ 50 _ASM_ALIGN "\n" \
44 _ASM_PTR #from "," #to "\n" \ 51 _ASM_PTR #from "," #to "\n" \
45 " .previous\n" 52 " .previous\n"
53#endif
46 54
47#endif /* _ASM_X86_ASM_H */ 55#endif /* _ASM_X86_ASM_H */
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 4a28d22d4793..847fee6493a2 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -95,6 +95,7 @@
95#define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */ 95#define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */
96#define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ 96#define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
97#define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */ 97#define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */
98#define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */
98 99
99/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ 100/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
100#define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ 101#define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h
index c68c361697e1..4d447b732d82 100644
--- a/arch/x86/include/asm/current.h
+++ b/arch/x86/include/asm/current.h
@@ -11,7 +11,7 @@ DECLARE_PER_CPU(struct task_struct *, current_task);
11 11
12static __always_inline struct task_struct *get_current(void) 12static __always_inline struct task_struct *get_current(void)
13{ 13{
14 return percpu_read(current_task); 14 return percpu_read_stable(current_task);
15} 15}
16 16
17#define current get_current() 17#define current get_current()
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index c993e9e0fed4..e8de2f6f5ca5 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -291,11 +291,24 @@ static inline unsigned long get_desc_base(const struct desc_struct *desc)
291 return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); 291 return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
292} 292}
293 293
294static inline void set_desc_base(struct desc_struct *desc, unsigned long base)
295{
296 desc->base0 = base & 0xffff;
297 desc->base1 = (base >> 16) & 0xff;
298 desc->base2 = (base >> 24) & 0xff;
299}
300
294static inline unsigned long get_desc_limit(const struct desc_struct *desc) 301static inline unsigned long get_desc_limit(const struct desc_struct *desc)
295{ 302{
296 return desc->limit0 | (desc->limit << 16); 303 return desc->limit0 | (desc->limit << 16);
297} 304}
298 305
306static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
307{
308 desc->limit0 = limit & 0xffff;
309 desc->limit = (limit >> 16) & 0xf;
310}
311
299static inline void _set_gate(int gate, unsigned type, void *addr, 312static inline void _set_gate(int gate, unsigned type, void *addr,
300 unsigned dpl, unsigned ist, unsigned seg) 313 unsigned dpl, unsigned ist, unsigned seg)
301{ 314{
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
index a6adefa28b94..9d6684849fd9 100644
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -34,6 +34,12 @@ struct desc_struct {
34 }; 34 };
35} __attribute__((packed)); 35} __attribute__((packed));
36 36
37#define GDT_ENTRY_INIT(flags, base, limit) { { { \
38 .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \
39 .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \
40 ((limit) & 0xf0000) | ((base) & 0xff000000), \
41 } } }
42
37enum { 43enum {
38 GATE_INTERRUPT = 0xE, 44 GATE_INTERRUPT = 0xE,
39 GATE_TRAP = 0xF, 45 GATE_TRAP = 0xF,
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 4994a20acbcb..cee34e9ca45b 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -13,4 +13,7 @@ struct dma_map_ops *dma_ops;
13#endif 13#endif
14}; 14};
15 15
16struct pdev_archdata {
17};
18
16#endif /* _ASM_X86_DEVICE_H */ 19#endif /* _ASM_X86_DEVICE_H */
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 1c3f9435f1c9..0ee770d23d0e 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -55,6 +55,24 @@ extern int dma_set_mask(struct device *dev, u64 mask);
55extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, 55extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
56 dma_addr_t *dma_addr, gfp_t flag); 56 dma_addr_t *dma_addr, gfp_t flag);
57 57
58static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
59{
60 if (!dev->dma_mask)
61 return 0;
62
63 return addr + size <= *dev->dma_mask;
64}
65
66static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
67{
68 return paddr;
69}
70
71static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
72{
73 return daddr;
74}
75
58static inline void 76static inline void
59dma_cache_sync(struct device *dev, void *vaddr, size_t size, 77dma_cache_sync(struct device *dev, void *vaddr, size_t size,
60 enum dma_data_direction dir) 78 enum dma_data_direction dir)
diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h
index 3afc5e87cfdd..ae6253ab9029 100644
--- a/arch/x86/include/asm/dwarf2.h
+++ b/arch/x86/include/asm/dwarf2.h
@@ -87,9 +87,25 @@
87 CFI_RESTORE \reg 87 CFI_RESTORE \reg
88 .endm 88 .endm
89#else /*!CONFIG_X86_64*/ 89#else /*!CONFIG_X86_64*/
90 .macro pushl_cfi reg
91 pushl \reg
92 CFI_ADJUST_CFA_OFFSET 4
93 .endm
90 94
91 /* 32bit defenitions are missed yet */ 95 .macro popl_cfi reg
96 popl \reg
97 CFI_ADJUST_CFA_OFFSET -4
98 .endm
92 99
100 .macro movl_cfi reg offset=0
101 movl %\reg, \offset(%esp)
102 CFI_REL_OFFSET \reg, \offset
103 .endm
104
105 .macro movl_cfi_restore offset reg
106 movl \offset(%esp), %\reg
107 CFI_RESTORE \reg
108 .endm
93#endif /*!CONFIG_X86_64*/ 109#endif /*!CONFIG_X86_64*/
94#endif /*__ASSEMBLY__*/ 110#endif /*__ASSEMBLY__*/
95 111
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 175adf58dd4f..0b20bbb758f2 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -26,6 +26,7 @@ extern void fpu_init(void);
26extern void mxcsr_feature_mask_init(void); 26extern void mxcsr_feature_mask_init(void);
27extern int init_fpu(struct task_struct *child); 27extern int init_fpu(struct task_struct *child);
28extern asmlinkage void math_state_restore(void); 28extern asmlinkage void math_state_restore(void);
29extern void __math_state_restore(void);
29extern void init_thread_xstate(void); 30extern void init_thread_xstate(void);
30extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); 31extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
31 32
@@ -301,6 +302,14 @@ static inline void kernel_fpu_end(void)
301 preempt_enable(); 302 preempt_enable();
302} 303}
303 304
305static inline bool irq_fpu_usable(void)
306{
307 struct pt_regs *regs;
308
309 return !in_interrupt() || !(regs = get_irq_regs()) || \
310 user_mode(regs) || (read_cr0() & X86_CR0_TS);
311}
312
304/* 313/*
305 * Some instructions like VIA's padlock instructions generate a spurious 314 * Some instructions like VIA's padlock instructions generate a spurious
306 * DNA fault but don't modify SSE registers. And these instructions 315 * DNA fault but don't modify SSE registers. And these instructions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 330ee807f89e..85232d32fcb8 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -150,11 +150,10 @@ extern int timer_through_8259;
150#define io_apic_assign_pci_irqs \ 150#define io_apic_assign_pci_irqs \
151 (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) 151 (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
152 152
153#ifdef CONFIG_ACPI 153extern u8 io_apic_unique_id(u8 id);
154extern int io_apic_get_unique_id(int ioapic, int apic_id); 154extern int io_apic_get_unique_id(int ioapic, int apic_id);
155extern int io_apic_get_version(int ioapic); 155extern int io_apic_get_version(int ioapic);
156extern int io_apic_get_redir_entries(int ioapic); 156extern int io_apic_get_redir_entries(int ioapic);
157#endif /* CONFIG_ACPI */
158 157
159struct io_apic_irq_attr; 158struct io_apic_irq_attr;
160extern int io_apic_set_pci_routing(struct device *dev, int irq, 159extern int io_apic_set_pci_routing(struct device *dev, int irq,
@@ -177,6 +176,16 @@ extern int setup_ioapic_entry(int apic, int irq,
177 int polarity, int vector, int pin); 176 int polarity, int vector, int pin);
178extern void ioapic_write_entry(int apic, int pin, 177extern void ioapic_write_entry(int apic, int pin,
179 struct IO_APIC_route_entry e); 178 struct IO_APIC_route_entry e);
179
180struct mp_ioapic_gsi{
181 int gsi_base;
182 int gsi_end;
183};
184extern struct mp_ioapic_gsi mp_gsi_routing[];
185int mp_find_ioapic(int gsi);
186int mp_find_ioapic_pin(int ioapic, int gsi);
187void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
188
180#else /* !CONFIG_X86_IO_APIC */ 189#else /* !CONFIG_X86_IO_APIC */
181#define io_apic_assign_pci_irqs 0 190#define io_apic_assign_pci_irqs 0
182static const int timer_through_8259 = 0; 191static const int timer_through_8259 = 0;
diff --git a/arch/x86/include/asm/ioctls.h b/arch/x86/include/asm/ioctls.h
index 0d5b23b7b06e..ec34c760665e 100644
--- a/arch/x86/include/asm/ioctls.h
+++ b/arch/x86/include/asm/ioctls.h
@@ -1,94 +1 @@
1#ifndef _ASM_X86_IOCTLS_H #include <asm-generic/ioctls.h>
2#define _ASM_X86_IOCTLS_H
3
4#include <asm/ioctl.h>
5
6/* 0x54 is just a magic number to make these relatively unique ('T') */
7
8#define TCGETS 0x5401
9#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
10#define TCSETSW 0x5403
11#define TCSETSF 0x5404
12#define TCGETA 0x5405
13#define TCSETA 0x5406
14#define TCSETAW 0x5407
15#define TCSETAF 0x5408
16#define TCSBRK 0x5409
17#define TCXONC 0x540A
18#define TCFLSH 0x540B
19#define TIOCEXCL 0x540C
20#define TIOCNXCL 0x540D
21#define TIOCSCTTY 0x540E
22#define TIOCGPGRP 0x540F
23#define TIOCSPGRP 0x5410
24#define TIOCOUTQ 0x5411
25#define TIOCSTI 0x5412
26#define TIOCGWINSZ 0x5413
27#define TIOCSWINSZ 0x5414
28#define TIOCMGET 0x5415
29#define TIOCMBIS 0x5416
30#define TIOCMBIC 0x5417
31#define TIOCMSET 0x5418
32#define TIOCGSOFTCAR 0x5419
33#define TIOCSSOFTCAR 0x541A
34#define FIONREAD 0x541B
35#define TIOCINQ FIONREAD
36#define TIOCLINUX 0x541C
37#define TIOCCONS 0x541D
38#define TIOCGSERIAL 0x541E
39#define TIOCSSERIAL 0x541F
40#define TIOCPKT 0x5420
41#define FIONBIO 0x5421
42#define TIOCNOTTY 0x5422
43#define TIOCSETD 0x5423
44#define TIOCGETD 0x5424
45#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
46/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
47#define TIOCSBRK 0x5427 /* BSD compatibility */
48#define TIOCCBRK 0x5428 /* BSD compatibility */
49#define TIOCGSID 0x5429 /* Return the session ID of FD */
50#define TCGETS2 _IOR('T', 0x2A, struct termios2)
51#define TCSETS2 _IOW('T', 0x2B, struct termios2)
52#define TCSETSW2 _IOW('T', 0x2C, struct termios2)
53#define TCSETSF2 _IOW('T', 0x2D, struct termios2)
54#define TIOCGRS485 0x542E
55#define TIOCSRS485 0x542F
56#define TIOCGPTN _IOR('T', 0x30, unsigned int)
57 /* Get Pty Number (of pty-mux device) */
58#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
59#define TCGETX 0x5432 /* SYS5 TCGETX compatibility */
60#define TCSETX 0x5433
61#define TCSETXF 0x5434
62#define TCSETXW 0x5435
63
64#define FIONCLEX 0x5450
65#define FIOCLEX 0x5451
66#define FIOASYNC 0x5452
67#define TIOCSERCONFIG 0x5453
68#define TIOCSERGWILD 0x5454
69#define TIOCSERSWILD 0x5455
70#define TIOCGLCKTRMIOS 0x5456
71#define TIOCSLCKTRMIOS 0x5457
72#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
73#define TIOCSERGETLSR 0x5459 /* Get line status register */
74#define TIOCSERGETMULTI 0x545A /* Get multiport config */
75#define TIOCSERSETMULTI 0x545B /* Set multiport config */
76
77#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
78#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
79#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
80#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
81#define FIOQSIZE 0x5460
82
83/* Used for packet mode */
84#define TIOCPKT_DATA 0
85#define TIOCPKT_FLUSHREAD 1
86#define TIOCPKT_FLUSHWRITE 2
87#define TIOCPKT_STOP 4
88#define TIOCPKT_START 8
89#define TIOCPKT_NOSTOP 16
90#define TIOCPKT_DOSTOP 32
91
92#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
93
94#endif /* _ASM_X86_IOCTLS_H */
diff --git a/arch/x86/include/asm/ipcbuf.h b/arch/x86/include/asm/ipcbuf.h
index ee678fd51594..84c7e51cb6d0 100644
--- a/arch/x86/include/asm/ipcbuf.h
+++ b/arch/x86/include/asm/ipcbuf.h
@@ -1,28 +1 @@
1#ifndef _ASM_X86_IPCBUF_H #include <asm-generic/ipcbuf.h>
2#define _ASM_X86_IPCBUF_H
3
4/*
5 * The ipc64_perm structure for x86 architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space is left for:
10 * - 32-bit mode_t and seq
11 * - 2 miscellaneous 32-bit values
12 */
13
14struct ipc64_perm {
15 __kernel_key_t key;
16 __kernel_uid32_t uid;
17 __kernel_gid32_t gid;
18 __kernel_uid32_t cuid;
19 __kernel_gid32_t cgid;
20 __kernel_mode_t mode;
21 unsigned short __pad1;
22 unsigned short seq;
23 unsigned short __pad2;
24 unsigned long __unused1;
25 unsigned long __unused2;
26};
27
28#endif /* _ASM_X86_IPCBUF_H */
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index c6ccbe7e81ad..9e2b952f810a 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -13,14 +13,13 @@ static inline unsigned long native_save_fl(void)
13 unsigned long flags; 13 unsigned long flags;
14 14
15 /* 15 /*
16 * Note: this needs to be "=r" not "=rm", because we have the 16 * "=rm" is safe here, because "pop" adjusts the stack before
17 * stack offset from what gcc expects at the time the "pop" is 17 * it evaluates its effective address -- this is part of the
18 * executed, and so a memory reference with respect to the stack 18 * documented behavior of the "pop" instruction.
19 * would end up using the wrong address.
20 */ 19 */
21 asm volatile("# __raw_save_flags\n\t" 20 asm volatile("# __raw_save_flags\n\t"
22 "pushf ; pop %0" 21 "pushf ; pop %0"
23 : "=r" (flags) 22 : "=rm" (flags)
24 : /* no input */ 23 : /* no input */
25 : "memory"); 24 : "memory");
26 25
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 125be8b19568..4a5fe914dc59 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -17,6 +17,8 @@
17#define __KVM_HAVE_USER_NMI 17#define __KVM_HAVE_USER_NMI
18#define __KVM_HAVE_GUEST_DEBUG 18#define __KVM_HAVE_GUEST_DEBUG
19#define __KVM_HAVE_MSIX 19#define __KVM_HAVE_MSIX
20#define __KVM_HAVE_MCE
21#define __KVM_HAVE_PIT_STATE2
20 22
21/* Architectural interrupt line count. */ 23/* Architectural interrupt line count. */
22#define KVM_NR_INTERRUPTS 256 24#define KVM_NR_INTERRUPTS 256
@@ -236,6 +238,14 @@ struct kvm_pit_state {
236 struct kvm_pit_channel_state channels[3]; 238 struct kvm_pit_channel_state channels[3];
237}; 239};
238 240
241#define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001
242
243struct kvm_pit_state2 {
244 struct kvm_pit_channel_state channels[3];
245 __u32 flags;
246 __u32 reserved[9];
247};
248
239struct kvm_reinject_control { 249struct kvm_reinject_control {
240 __u8 pit_reinject; 250 __u8 pit_reinject;
241 __u8 reserved[31]; 251 __u8 reserved[31];
diff --git a/arch/x86/include/asm/kvm_x86_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index b7ed2c423116..b7ed2c423116 100644
--- a/arch/x86/include/asm/kvm_x86_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index eabdc1cfab5c..3be000435fad 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -14,6 +14,7 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/mmu_notifier.h> 16#include <linux/mmu_notifier.h>
17#include <linux/tracepoint.h>
17 18
18#include <linux/kvm.h> 19#include <linux/kvm.h>
19#include <linux/kvm_para.h> 20#include <linux/kvm_para.h>
@@ -37,12 +38,14 @@
37#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS | \ 38#define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS | \
38 0xFFFFFF0000000000ULL) 39 0xFFFFFF0000000000ULL)
39 40
40#define KVM_GUEST_CR0_MASK \ 41#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \
41 (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE \ 42 (X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD)
42 | X86_CR0_NW | X86_CR0_CD) 43#define KVM_GUEST_CR0_MASK \
44 (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
45#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST \
46 (X86_CR0_WP | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP)
43#define KVM_VM_CR0_ALWAYS_ON \ 47#define KVM_VM_CR0_ALWAYS_ON \
44 (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE | X86_CR0_TS \ 48 (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
45 | X86_CR0_MP)
46#define KVM_GUEST_CR4_MASK \ 49#define KVM_GUEST_CR4_MASK \
47 (X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE) 50 (X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE)
48#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) 51#define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
@@ -51,12 +54,12 @@
51#define INVALID_PAGE (~(hpa_t)0) 54#define INVALID_PAGE (~(hpa_t)0)
52#define UNMAPPED_GVA (~(gpa_t)0) 55#define UNMAPPED_GVA (~(gpa_t)0)
53 56
54/* shadow tables are PAE even on non-PAE hosts */ 57/* KVM Hugepage definitions for x86 */
55#define KVM_HPAGE_SHIFT 21 58#define KVM_NR_PAGE_SIZES 3
56#define KVM_HPAGE_SIZE (1UL << KVM_HPAGE_SHIFT) 59#define KVM_HPAGE_SHIFT(x) (PAGE_SHIFT + (((x) - 1) * 9))
57#define KVM_HPAGE_MASK (~(KVM_HPAGE_SIZE - 1)) 60#define KVM_HPAGE_SIZE(x) (1UL << KVM_HPAGE_SHIFT(x))
58 61#define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1))
59#define KVM_PAGES_PER_HPAGE (KVM_HPAGE_SIZE / PAGE_SIZE) 62#define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE)
60 63
61#define DE_VECTOR 0 64#define DE_VECTOR 0
62#define DB_VECTOR 1 65#define DB_VECTOR 1
@@ -120,6 +123,10 @@ enum kvm_reg {
120 NR_VCPU_REGS 123 NR_VCPU_REGS
121}; 124};
122 125
126enum kvm_reg_ex {
127 VCPU_EXREG_PDPTR = NR_VCPU_REGS,
128};
129
123enum { 130enum {
124 VCPU_SREG_ES, 131 VCPU_SREG_ES,
125 VCPU_SREG_CS, 132 VCPU_SREG_CS,
@@ -131,7 +138,7 @@ enum {
131 VCPU_SREG_LDTR, 138 VCPU_SREG_LDTR,
132}; 139};
133 140
134#include <asm/kvm_x86_emulate.h> 141#include <asm/kvm_emulate.h>
135 142
136#define KVM_NR_MEM_OBJS 40 143#define KVM_NR_MEM_OBJS 40
137 144
@@ -308,7 +315,6 @@ struct kvm_vcpu_arch {
308 struct { 315 struct {
309 gfn_t gfn; /* presumed gfn during guest pte update */ 316 gfn_t gfn; /* presumed gfn during guest pte update */
310 pfn_t pfn; /* pfn corresponding to that gfn */ 317 pfn_t pfn; /* pfn corresponding to that gfn */
311 int largepage;
312 unsigned long mmu_seq; 318 unsigned long mmu_seq;
313 } update_pte; 319 } update_pte;
314 320
@@ -334,16 +340,6 @@ struct kvm_vcpu_arch {
334 u8 nr; 340 u8 nr;
335 } interrupt; 341 } interrupt;
336 342
337 struct {
338 int vm86_active;
339 u8 save_iopl;
340 struct kvm_save_segment {
341 u16 selector;
342 unsigned long base;
343 u32 limit;
344 u32 ar;
345 } tr, es, ds, fs, gs;
346 } rmode;
347 int halt_request; /* real mode on Intel only */ 343 int halt_request; /* real mode on Intel only */
348 344
349 int cpuid_nent; 345 int cpuid_nent;
@@ -366,13 +362,15 @@ struct kvm_vcpu_arch {
366 u32 pat; 362 u32 pat;
367 363
368 int switch_db_regs; 364 int switch_db_regs;
369 unsigned long host_db[KVM_NR_DB_REGS];
370 unsigned long host_dr6;
371 unsigned long host_dr7;
372 unsigned long db[KVM_NR_DB_REGS]; 365 unsigned long db[KVM_NR_DB_REGS];
373 unsigned long dr6; 366 unsigned long dr6;
374 unsigned long dr7; 367 unsigned long dr7;
375 unsigned long eff_db[KVM_NR_DB_REGS]; 368 unsigned long eff_db[KVM_NR_DB_REGS];
369
370 u64 mcg_cap;
371 u64 mcg_status;
372 u64 mcg_ctl;
373 u64 *mce_banks;
376}; 374};
377 375
378struct kvm_mem_alias { 376struct kvm_mem_alias {
@@ -409,6 +407,7 @@ struct kvm_arch{
409 407
410 struct page *ept_identity_pagetable; 408 struct page *ept_identity_pagetable;
411 bool ept_identity_pagetable_done; 409 bool ept_identity_pagetable_done;
410 gpa_t ept_identity_map_addr;
412 411
413 unsigned long irq_sources_bitmap; 412 unsigned long irq_sources_bitmap;
414 unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; 413 unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
@@ -526,6 +525,9 @@ struct kvm_x86_ops {
526 int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); 525 int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
527 int (*get_tdp_level)(void); 526 int (*get_tdp_level)(void);
528 u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); 527 u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
528 bool (*gb_page_enable)(void);
529
530 const struct trace_print_flags *exit_reasons_str;
529}; 531};
530 532
531extern struct kvm_x86_ops *kvm_x86_ops; 533extern struct kvm_x86_ops *kvm_x86_ops;
@@ -618,6 +620,7 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
618void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); 620void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
619void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, 621void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
620 u32 error_code); 622 u32 error_code);
623bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
621 624
622int kvm_pic_set_irq(void *opaque, int irq, int level); 625int kvm_pic_set_irq(void *opaque, int irq, int level);
623 626
@@ -752,8 +755,6 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code)
752 kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); 755 kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
753} 756}
754 757
755#define MSR_IA32_TIME_STAMP_COUNTER 0x010
756
757#define TSS_IOPB_BASE_OFFSET 0x66 758#define TSS_IOPB_BASE_OFFSET 0x66
758#define TSS_BASE_SIZE 0x68 759#define TSS_BASE_SIZE 0x68
759#define TSS_IOPB_SIZE (65536 / 8) 760#define TSS_IOPB_SIZE (65536 / 8)
@@ -796,5 +797,8 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
796int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); 797int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
797int kvm_age_hva(struct kvm *kvm, unsigned long hva); 798int kvm_age_hva(struct kvm *kvm, unsigned long hva);
798int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); 799int cpuid_maxphyaddr(struct kvm_vcpu *vcpu);
800int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
801int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
802int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
799 803
800#endif /* _ASM_X86_KVM_HOST_H */ 804#endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index b8a3305ae093..c584076a47f4 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -1,6 +1,8 @@
1#ifndef _ASM_X86_KVM_PARA_H 1#ifndef _ASM_X86_KVM_PARA_H
2#define _ASM_X86_KVM_PARA_H 2#define _ASM_X86_KVM_PARA_H
3 3
4#include <linux/types.h>
5
4/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It 6/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It
5 * should be used to determine that a VM is running under KVM. 7 * should be used to determine that a VM is running under KVM.
6 */ 8 */
diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
index 5136dad57cbb..0d97deba1e35 100644
--- a/arch/x86/include/asm/lguest.h
+++ b/arch/x86/include/asm/lguest.h
@@ -90,8 +90,9 @@ static inline void lguest_set_ts(void)
90} 90}
91 91
92/* Full 4G segment descriptors, suitable for CS and DS. */ 92/* Full 4G segment descriptors, suitable for CS and DS. */
93#define FULL_EXEC_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9b00} } }) 93#define FULL_EXEC_SEGMENT \
94#define FULL_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9300} } }) 94 ((struct desc_struct)GDT_ENTRY_INIT(0xc09b, 0, 0xfffff))
95#define FULL_SEGMENT ((struct desc_struct)GDT_ENTRY_INIT(0xc093, 0, 0xfffff))
95 96
96#endif /* __ASSEMBLY__ */ 97#endif /* __ASSEMBLY__ */
97 98
diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h
index 751af2550ed9..593e51d4643f 100644
--- a/arch/x86/include/asm/mman.h
+++ b/arch/x86/include/asm/mman.h
@@ -1,20 +1,8 @@
1#ifndef _ASM_X86_MMAN_H 1#ifndef _ASM_X86_MMAN_H
2#define _ASM_X86_MMAN_H 2#define _ASM_X86_MMAN_H
3 3
4#include <asm-generic/mman-common.h>
5
6#define MAP_32BIT 0x40 /* only give out 32bit addresses */ 4#define MAP_32BIT 0x40 /* only give out 32bit addresses */
7 5
8#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ 6#include <asm-generic/mman.h>
9#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
10#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
11#define MAP_LOCKED 0x2000 /* pages are locked */
12#define MAP_NORESERVE 0x4000 /* don't check for reservations */
13#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
14#define MAP_NONBLOCK 0x10000 /* do not block on IO */
15#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */
16
17#define MCL_CURRENT 1 /* lock all current mappings */
18#define MCL_FUTURE 2 /* lock all future mappings */
19 7
20#endif /* _ASM_X86_MMAN_H */ 8#endif /* _ASM_X86_MMAN_H */
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
index 47d62743c4d5..3e2ce58a31a3 100644
--- a/arch/x86/include/asm/module.h
+++ b/arch/x86/include/asm/module.h
@@ -1,18 +1,7 @@
1#ifndef _ASM_X86_MODULE_H 1#ifndef _ASM_X86_MODULE_H
2#define _ASM_X86_MODULE_H 2#define _ASM_X86_MODULE_H
3 3
4/* x86_32/64 are simple */ 4#include <asm-generic/module.h>
5struct mod_arch_specific {};
6
7#ifdef CONFIG_X86_32
8# define Elf_Shdr Elf32_Shdr
9# define Elf_Sym Elf32_Sym
10# define Elf_Ehdr Elf32_Ehdr
11#else
12# define Elf_Shdr Elf64_Shdr
13# define Elf_Sym Elf64_Sym
14# define Elf_Ehdr Elf64_Ehdr
15#endif
16 5
17#ifdef CONFIG_X86_64 6#ifdef CONFIG_X86_64
18/* X86_64 does not define MODULE_PROC_FAMILY */ 7/* X86_64 does not define MODULE_PROC_FAMILY */
@@ -28,6 +17,8 @@ struct mod_arch_specific {};
28#define MODULE_PROC_FAMILY "586MMX " 17#define MODULE_PROC_FAMILY "586MMX "
29#elif defined CONFIG_MCORE2 18#elif defined CONFIG_MCORE2
30#define MODULE_PROC_FAMILY "CORE2 " 19#define MODULE_PROC_FAMILY "CORE2 "
20#elif defined CONFIG_MATOM
21#define MODULE_PROC_FAMILY "ATOM "
31#elif defined CONFIG_M686 22#elif defined CONFIG_M686
32#define MODULE_PROC_FAMILY "686 " 23#define MODULE_PROC_FAMILY "686 "
33#elif defined CONFIG_MPENTIUMII 24#elif defined CONFIG_MPENTIUMII
diff --git a/arch/x86/include/asm/msgbuf.h b/arch/x86/include/asm/msgbuf.h
index 7e4e9481f51c..809134c644a6 100644
--- a/arch/x86/include/asm/msgbuf.h
+++ b/arch/x86/include/asm/msgbuf.h
@@ -1,39 +1 @@
1#ifndef _ASM_X86_MSGBUF_H #include <asm-generic/msgbuf.h>
2#define _ASM_X86_MSGBUF_H
3
4/*
5 * The msqid64_ds structure for i386 architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space on i386 is left for:
10 * - 64-bit time_t to solve y2038 problem
11 * - 2 miscellaneous 32-bit values
12 *
13 * Pad space on x8664 is left for:
14 * - 2 miscellaneous 64-bit values
15 */
16struct msqid64_ds {
17 struct ipc64_perm msg_perm;
18 __kernel_time_t msg_stime; /* last msgsnd time */
19#ifdef __i386__
20 unsigned long __unused1;
21#endif
22 __kernel_time_t msg_rtime; /* last msgrcv time */
23#ifdef __i386__
24 unsigned long __unused2;
25#endif
26 __kernel_time_t msg_ctime; /* last change time */
27#ifdef __i386__
28 unsigned long __unused3;
29#endif
30 unsigned long msg_cbytes; /* current number of bytes on queue */
31 unsigned long msg_qnum; /* number of messages in queue */
32 unsigned long msg_qbytes; /* max number of bytes on queue */
33 __kernel_pid_t msg_lspid; /* pid of last msgsnd */
34 __kernel_pid_t msg_lrpid; /* last receive pid */
35 unsigned long __unused4;
36 unsigned long __unused5;
37};
38
39#endif /* _ASM_X86_MSGBUF_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6be7fc254b59..bd5549034a95 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -374,6 +374,7 @@
374/* AMD-V MSRs */ 374/* AMD-V MSRs */
375 375
376#define MSR_VM_CR 0xc0010114 376#define MSR_VM_CR 0xc0010114
377#define MSR_VM_IGNNE 0xc0010115
377#define MSR_VM_HSAVE_PA 0xc0010117 378#define MSR_VM_HSAVE_PA 0xc0010117
378 379
379#endif /* _ASM_X86_MSR_INDEX_H */ 380#endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 48ad9d29484a..7e2b6ba962ff 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -3,10 +3,16 @@
3 3
4#include <asm/msr-index.h> 4#include <asm/msr-index.h>
5 5
6#ifdef __KERNEL__
7#ifndef __ASSEMBLY__ 6#ifndef __ASSEMBLY__
8 7
9#include <linux/types.h> 8#include <linux/types.h>
9#include <linux/ioctl.h>
10
11#define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8])
12#define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8])
13
14#ifdef __KERNEL__
15
10#include <asm/asm.h> 16#include <asm/asm.h>
11#include <asm/errno.h> 17#include <asm/errno.h>
12#include <asm/cpumask.h> 18#include <asm/cpumask.h>
@@ -67,23 +73,7 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
67 ".previous\n\t" 73 ".previous\n\t"
68 _ASM_EXTABLE(2b, 3b) 74 _ASM_EXTABLE(2b, 3b)
69 : [err] "=r" (*err), EAX_EDX_RET(val, low, high) 75 : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
70 : "c" (msr), [fault] "i" (-EFAULT)); 76 : "c" (msr), [fault] "i" (-EIO));
71 return EAX_EDX_VAL(val, low, high);
72}
73
74static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
75 int *err)
76{
77 DECLARE_ARGS(val, low, high);
78
79 asm volatile("2: rdmsr ; xor %0,%0\n"
80 "1:\n\t"
81 ".section .fixup,\"ax\"\n\t"
82 "3: mov %3,%0 ; jmp 1b\n\t"
83 ".previous\n\t"
84 _ASM_EXTABLE(2b, 3b)
85 : "=r" (*err), EAX_EDX_RET(val, low, high)
86 : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
87 return EAX_EDX_VAL(val, low, high); 77 return EAX_EDX_VAL(val, low, high);
88} 78}
89 79
@@ -106,13 +96,16 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
106 _ASM_EXTABLE(2b, 3b) 96 _ASM_EXTABLE(2b, 3b)
107 : [err] "=a" (err) 97 : [err] "=a" (err)
108 : "c" (msr), "0" (low), "d" (high), 98 : "c" (msr), "0" (low), "d" (high),
109 [fault] "i" (-EFAULT) 99 [fault] "i" (-EIO)
110 : "memory"); 100 : "memory");
111 return err; 101 return err;
112} 102}
113 103
114extern unsigned long long native_read_tsc(void); 104extern unsigned long long native_read_tsc(void);
115 105
106extern int native_rdmsr_safe_regs(u32 regs[8]);
107extern int native_wrmsr_safe_regs(u32 regs[8]);
108
116static __always_inline unsigned long long __native_read_tsc(void) 109static __always_inline unsigned long long __native_read_tsc(void)
117{ 110{
118 DECLARE_ARGS(val, low, high); 111 DECLARE_ARGS(val, low, high);
@@ -181,14 +174,44 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
181 *p = native_read_msr_safe(msr, &err); 174 *p = native_read_msr_safe(msr, &err);
182 return err; 175 return err;
183} 176}
177
184static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) 178static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
185{ 179{
180 u32 gprs[8] = { 0 };
186 int err; 181 int err;
187 182
188 *p = native_read_msr_amd_safe(msr, &err); 183 gprs[1] = msr;
184 gprs[7] = 0x9c5a203a;
185
186 err = native_rdmsr_safe_regs(gprs);
187
188 *p = gprs[0] | ((u64)gprs[2] << 32);
189
189 return err; 190 return err;
190} 191}
191 192
193static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
194{
195 u32 gprs[8] = { 0 };
196
197 gprs[0] = (u32)val;
198 gprs[1] = msr;
199 gprs[2] = val >> 32;
200 gprs[7] = 0x9c5a203a;
201
202 return native_wrmsr_safe_regs(gprs);
203}
204
205static inline int rdmsr_safe_regs(u32 regs[8])
206{
207 return native_rdmsr_safe_regs(regs);
208}
209
210static inline int wrmsr_safe_regs(u32 regs[8])
211{
212 return native_wrmsr_safe_regs(regs);
213}
214
192#define rdtscl(low) \ 215#define rdtscl(low) \
193 ((low) = (u32)__native_read_tsc()) 216 ((low) = (u32)__native_read_tsc())
194 217
@@ -228,6 +251,8 @@ void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
228void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); 251void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
229int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); 252int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
230int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); 253int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
254int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
255int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
231#else /* CONFIG_SMP */ 256#else /* CONFIG_SMP */
232static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) 257static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
233{ 258{
@@ -258,7 +283,15 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
258{ 283{
259 return wrmsr_safe(msr_no, l, h); 284 return wrmsr_safe(msr_no, l, h);
260} 285}
286static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
287{
288 return rdmsr_safe_regs(regs);
289}
290static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
291{
292 return wrmsr_safe_regs(regs);
293}
261#endif /* CONFIG_SMP */ 294#endif /* CONFIG_SMP */
262#endif /* __ASSEMBLY__ */
263#endif /* __KERNEL__ */ 295#endif /* __KERNEL__ */
296#endif /* __ASSEMBLY__ */
264#endif /* _ASM_X86_MSR_H */ 297#endif /* _ASM_X86_MSR_H */
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h
index c86e5ed4af51..e63cf7d441e1 100644
--- a/arch/x86/include/asm/nmi.h
+++ b/arch/x86/include/asm/nmi.h
@@ -45,8 +45,8 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *,
45 void __user *, size_t *, loff_t *); 45 void __user *, size_t *, loff_t *);
46extern int unknown_nmi_panic; 46extern int unknown_nmi_panic;
47 47
48void __trigger_all_cpu_backtrace(void); 48void arch_trigger_all_cpu_backtrace(void);
49#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() 49#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
50 50
51static inline void localise_nmi_watchdog(void) 51static inline void localise_nmi_watchdog(void)
52{ 52{
diff --git a/arch/x86/include/asm/param.h b/arch/x86/include/asm/param.h
index 6f0d0422f4ca..965d45427975 100644
--- a/arch/x86/include/asm/param.h
+++ b/arch/x86/include/asm/param.h
@@ -1,22 +1 @@
1#ifndef _ASM_X86_PARAM_H #include <asm-generic/param.h>
2#define _ASM_X86_PARAM_H
3
4#ifdef __KERNEL__
5# define HZ CONFIG_HZ /* Internal kernel timer frequency */
6# define USER_HZ 100 /* some user interfaces are */
7# define CLOCKS_PER_SEC (USER_HZ) /* in "ticks" like times() */
8#endif
9
10#ifndef HZ
11#define HZ 100
12#endif
13
14#define EXEC_PAGESIZE 4096
15
16#ifndef NOGROUP
17#define NOGROUP (-1)
18#endif
19
20#define MAXHOSTNAMELEN 64 /* max length of hostname */
21
22#endif /* _ASM_X86_PARAM_H */
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 4fb37c8a0832..40d6586af25b 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -7,689 +7,11 @@
7#include <asm/pgtable_types.h> 7#include <asm/pgtable_types.h>
8#include <asm/asm.h> 8#include <asm/asm.h>
9 9
10/* Bitmask of what can be clobbered: usually at least eax. */ 10#include <asm/paravirt_types.h>
11#define CLBR_NONE 0
12#define CLBR_EAX (1 << 0)
13#define CLBR_ECX (1 << 1)
14#define CLBR_EDX (1 << 2)
15#define CLBR_EDI (1 << 3)
16
17#ifdef CONFIG_X86_32
18/* CLBR_ANY should match all regs platform has. For i386, that's just it */
19#define CLBR_ANY ((1 << 4) - 1)
20
21#define CLBR_ARG_REGS (CLBR_EAX | CLBR_EDX | CLBR_ECX)
22#define CLBR_RET_REG (CLBR_EAX | CLBR_EDX)
23#define CLBR_SCRATCH (0)
24#else
25#define CLBR_RAX CLBR_EAX
26#define CLBR_RCX CLBR_ECX
27#define CLBR_RDX CLBR_EDX
28#define CLBR_RDI CLBR_EDI
29#define CLBR_RSI (1 << 4)
30#define CLBR_R8 (1 << 5)
31#define CLBR_R9 (1 << 6)
32#define CLBR_R10 (1 << 7)
33#define CLBR_R11 (1 << 8)
34
35#define CLBR_ANY ((1 << 9) - 1)
36
37#define CLBR_ARG_REGS (CLBR_RDI | CLBR_RSI | CLBR_RDX | \
38 CLBR_RCX | CLBR_R8 | CLBR_R9)
39#define CLBR_RET_REG (CLBR_RAX)
40#define CLBR_SCRATCH (CLBR_R10 | CLBR_R11)
41
42#include <asm/desc_defs.h>
43#endif /* X86_64 */
44
45#define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG)
46 11
47#ifndef __ASSEMBLY__ 12#ifndef __ASSEMBLY__
48#include <linux/types.h> 13#include <linux/types.h>
49#include <linux/cpumask.h> 14#include <linux/cpumask.h>
50#include <asm/kmap_types.h>
51#include <asm/desc_defs.h>
52
53struct page;
54struct thread_struct;
55struct desc_ptr;
56struct tss_struct;
57struct mm_struct;
58struct desc_struct;
59struct task_struct;
60
61/*
62 * Wrapper type for pointers to code which uses the non-standard
63 * calling convention. See PV_CALL_SAVE_REGS_THUNK below.
64 */
65struct paravirt_callee_save {
66 void *func;
67};
68
69/* general info */
70struct pv_info {
71 unsigned int kernel_rpl;
72 int shared_kernel_pmd;
73 int paravirt_enabled;
74 const char *name;
75};
76
77struct pv_init_ops {
78 /*
79 * Patch may replace one of the defined code sequences with
80 * arbitrary code, subject to the same register constraints.
81 * This generally means the code is not free to clobber any
82 * registers other than EAX. The patch function should return
83 * the number of bytes of code generated, as we nop pad the
84 * rest in generic code.
85 */
86 unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
87 unsigned long addr, unsigned len);
88
89 /* Basic arch-specific setup */
90 void (*arch_setup)(void);
91 char *(*memory_setup)(void);
92 void (*post_allocator_init)(void);
93
94 /* Print a banner to identify the environment */
95 void (*banner)(void);
96};
97
98
99struct pv_lazy_ops {
100 /* Set deferred update mode, used for batching operations. */
101 void (*enter)(void);
102 void (*leave)(void);
103};
104
105struct pv_time_ops {
106 void (*time_init)(void);
107
108 /* Set and set time of day */
109 unsigned long (*get_wallclock)(void);
110 int (*set_wallclock)(unsigned long);
111
112 unsigned long long (*sched_clock)(void);
113 unsigned long (*get_tsc_khz)(void);
114};
115
116struct pv_cpu_ops {
117 /* hooks for various privileged instructions */
118 unsigned long (*get_debugreg)(int regno);
119 void (*set_debugreg)(int regno, unsigned long value);
120
121 void (*clts)(void);
122
123 unsigned long (*read_cr0)(void);
124 void (*write_cr0)(unsigned long);
125
126 unsigned long (*read_cr4_safe)(void);
127 unsigned long (*read_cr4)(void);
128 void (*write_cr4)(unsigned long);
129
130#ifdef CONFIG_X86_64
131 unsigned long (*read_cr8)(void);
132 void (*write_cr8)(unsigned long);
133#endif
134
135 /* Segment descriptor handling */
136 void (*load_tr_desc)(void);
137 void (*load_gdt)(const struct desc_ptr *);
138 void (*load_idt)(const struct desc_ptr *);
139 void (*store_gdt)(struct desc_ptr *);
140 void (*store_idt)(struct desc_ptr *);
141 void (*set_ldt)(const void *desc, unsigned entries);
142 unsigned long (*store_tr)(void);
143 void (*load_tls)(struct thread_struct *t, unsigned int cpu);
144#ifdef CONFIG_X86_64
145 void (*load_gs_index)(unsigned int idx);
146#endif
147 void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum,
148 const void *desc);
149 void (*write_gdt_entry)(struct desc_struct *,
150 int entrynum, const void *desc, int size);
151 void (*write_idt_entry)(gate_desc *,
152 int entrynum, const gate_desc *gate);
153 void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries);
154 void (*free_ldt)(struct desc_struct *ldt, unsigned entries);
155
156 void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
157
158 void (*set_iopl_mask)(unsigned mask);
159
160 void (*wbinvd)(void);
161 void (*io_delay)(void);
162
163 /* cpuid emulation, mostly so that caps bits can be disabled */
164 void (*cpuid)(unsigned int *eax, unsigned int *ebx,
165 unsigned int *ecx, unsigned int *edx);
166
167 /* MSR, PMC and TSR operations.
168 err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
169 u64 (*read_msr_amd)(unsigned int msr, int *err);
170 u64 (*read_msr)(unsigned int msr, int *err);
171 int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
172
173 u64 (*read_tsc)(void);
174 u64 (*read_pmc)(int counter);
175 unsigned long long (*read_tscp)(unsigned int *aux);
176
177 /*
178 * Atomically enable interrupts and return to userspace. This
179 * is only ever used to return to 32-bit processes; in a
180 * 64-bit kernel, it's used for 32-on-64 compat processes, but
181 * never native 64-bit processes. (Jump, not call.)
182 */
183 void (*irq_enable_sysexit)(void);
184
185 /*
186 * Switch to usermode gs and return to 64-bit usermode using
187 * sysret. Only used in 64-bit kernels to return to 64-bit
188 * processes. Usermode register state, including %rsp, must
189 * already be restored.
190 */
191 void (*usergs_sysret64)(void);
192
193 /*
194 * Switch to usermode gs and return to 32-bit usermode using
195 * sysret. Used to return to 32-on-64 compat processes.
196 * Other usermode register state, including %esp, must already
197 * be restored.
198 */
199 void (*usergs_sysret32)(void);
200
201 /* Normal iret. Jump to this with the standard iret stack
202 frame set up. */
203 void (*iret)(void);
204
205 void (*swapgs)(void);
206
207 void (*start_context_switch)(struct task_struct *prev);
208 void (*end_context_switch)(struct task_struct *next);
209};
210
211struct pv_irq_ops {
212 void (*init_IRQ)(void);
213
214 /*
215 * Get/set interrupt state. save_fl and restore_fl are only
216 * expected to use X86_EFLAGS_IF; all other bits
217 * returned from save_fl are undefined, and may be ignored by
218 * restore_fl.
219 *
220 * NOTE: These functions callers expect the callee to preserve
221 * more registers than the standard C calling convention.
222 */
223 struct paravirt_callee_save save_fl;
224 struct paravirt_callee_save restore_fl;
225 struct paravirt_callee_save irq_disable;
226 struct paravirt_callee_save irq_enable;
227
228 void (*safe_halt)(void);
229 void (*halt)(void);
230
231#ifdef CONFIG_X86_64
232 void (*adjust_exception_frame)(void);
233#endif
234};
235
236struct pv_apic_ops {
237#ifdef CONFIG_X86_LOCAL_APIC
238 void (*setup_boot_clock)(void);
239 void (*setup_secondary_clock)(void);
240
241 void (*startup_ipi_hook)(int phys_apicid,
242 unsigned long start_eip,
243 unsigned long start_esp);
244#endif
245};
246
247struct pv_mmu_ops {
248 /*
249 * Called before/after init_mm pagetable setup. setup_start
250 * may reset %cr3, and may pre-install parts of the pagetable;
251 * pagetable setup is expected to preserve any existing
252 * mapping.
253 */
254 void (*pagetable_setup_start)(pgd_t *pgd_base);
255 void (*pagetable_setup_done)(pgd_t *pgd_base);
256
257 unsigned long (*read_cr2)(void);
258 void (*write_cr2)(unsigned long);
259
260 unsigned long (*read_cr3)(void);
261 void (*write_cr3)(unsigned long);
262
263 /*
264 * Hooks for intercepting the creation/use/destruction of an
265 * mm_struct.
266 */
267 void (*activate_mm)(struct mm_struct *prev,
268 struct mm_struct *next);
269 void (*dup_mmap)(struct mm_struct *oldmm,
270 struct mm_struct *mm);
271 void (*exit_mmap)(struct mm_struct *mm);
272
273
274 /* TLB operations */
275 void (*flush_tlb_user)(void);
276 void (*flush_tlb_kernel)(void);
277 void (*flush_tlb_single)(unsigned long addr);
278 void (*flush_tlb_others)(const struct cpumask *cpus,
279 struct mm_struct *mm,
280 unsigned long va);
281
282 /* Hooks for allocating and freeing a pagetable top-level */
283 int (*pgd_alloc)(struct mm_struct *mm);
284 void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd);
285
286 /*
287 * Hooks for allocating/releasing pagetable pages when they're
288 * attached to a pagetable
289 */
290 void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
291 void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
292 void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
293 void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
294 void (*release_pte)(unsigned long pfn);
295 void (*release_pmd)(unsigned long pfn);
296 void (*release_pud)(unsigned long pfn);
297
298 /* Pagetable manipulation functions */
299 void (*set_pte)(pte_t *ptep, pte_t pteval);
300 void (*set_pte_at)(struct mm_struct *mm, unsigned long addr,
301 pte_t *ptep, pte_t pteval);
302 void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
303 void (*pte_update)(struct mm_struct *mm, unsigned long addr,
304 pte_t *ptep);
305 void (*pte_update_defer)(struct mm_struct *mm,
306 unsigned long addr, pte_t *ptep);
307
308 pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
309 pte_t *ptep);
310 void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
311 pte_t *ptep, pte_t pte);
312
313 struct paravirt_callee_save pte_val;
314 struct paravirt_callee_save make_pte;
315
316 struct paravirt_callee_save pgd_val;
317 struct paravirt_callee_save make_pgd;
318
319#if PAGETABLE_LEVELS >= 3
320#ifdef CONFIG_X86_PAE
321 void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
322 void (*pte_clear)(struct mm_struct *mm, unsigned long addr,
323 pte_t *ptep);
324 void (*pmd_clear)(pmd_t *pmdp);
325
326#endif /* CONFIG_X86_PAE */
327
328 void (*set_pud)(pud_t *pudp, pud_t pudval);
329
330 struct paravirt_callee_save pmd_val;
331 struct paravirt_callee_save make_pmd;
332
333#if PAGETABLE_LEVELS == 4
334 struct paravirt_callee_save pud_val;
335 struct paravirt_callee_save make_pud;
336
337 void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
338#endif /* PAGETABLE_LEVELS == 4 */
339#endif /* PAGETABLE_LEVELS >= 3 */
340
341#ifdef CONFIG_HIGHPTE
342 void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
343#endif
344
345 struct pv_lazy_ops lazy_mode;
346
347 /* dom0 ops */
348
349 /* Sometimes the physical address is a pfn, and sometimes its
350 an mfn. We can tell which is which from the index. */
351 void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
352 phys_addr_t phys, pgprot_t flags);
353};
354
355struct raw_spinlock;
356struct pv_lock_ops {
357 int (*spin_is_locked)(struct raw_spinlock *lock);
358 int (*spin_is_contended)(struct raw_spinlock *lock);
359 void (*spin_lock)(struct raw_spinlock *lock);
360 void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags);
361 int (*spin_trylock)(struct raw_spinlock *lock);
362 void (*spin_unlock)(struct raw_spinlock *lock);
363};
364
365/* This contains all the paravirt structures: we get a convenient
366 * number for each function using the offset which we use to indicate
367 * what to patch. */
368struct paravirt_patch_template {
369 struct pv_init_ops pv_init_ops;
370 struct pv_time_ops pv_time_ops;
371 struct pv_cpu_ops pv_cpu_ops;
372 struct pv_irq_ops pv_irq_ops;
373 struct pv_apic_ops pv_apic_ops;
374 struct pv_mmu_ops pv_mmu_ops;
375 struct pv_lock_ops pv_lock_ops;
376};
377
378extern struct pv_info pv_info;
379extern struct pv_init_ops pv_init_ops;
380extern struct pv_time_ops pv_time_ops;
381extern struct pv_cpu_ops pv_cpu_ops;
382extern struct pv_irq_ops pv_irq_ops;
383extern struct pv_apic_ops pv_apic_ops;
384extern struct pv_mmu_ops pv_mmu_ops;
385extern struct pv_lock_ops pv_lock_ops;
386
387#define PARAVIRT_PATCH(x) \
388 (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
389
390#define paravirt_type(op) \
391 [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \
392 [paravirt_opptr] "i" (&(op))
393#define paravirt_clobber(clobber) \
394 [paravirt_clobber] "i" (clobber)
395
396/*
397 * Generate some code, and mark it as patchable by the
398 * apply_paravirt() alternate instruction patcher.
399 */
400#define _paravirt_alt(insn_string, type, clobber) \
401 "771:\n\t" insn_string "\n" "772:\n" \
402 ".pushsection .parainstructions,\"a\"\n" \
403 _ASM_ALIGN "\n" \
404 _ASM_PTR " 771b\n" \
405 " .byte " type "\n" \
406 " .byte 772b-771b\n" \
407 " .short " clobber "\n" \
408 ".popsection\n"
409
410/* Generate patchable code, with the default asm parameters. */
411#define paravirt_alt(insn_string) \
412 _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
413
414/* Simple instruction patching code. */
415#define DEF_NATIVE(ops, name, code) \
416 extern const char start_##ops##_##name[], end_##ops##_##name[]; \
417 asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
418
419unsigned paravirt_patch_nop(void);
420unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
421unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
422unsigned paravirt_patch_ignore(unsigned len);
423unsigned paravirt_patch_call(void *insnbuf,
424 const void *target, u16 tgt_clobbers,
425 unsigned long addr, u16 site_clobbers,
426 unsigned len);
427unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
428 unsigned long addr, unsigned len);
429unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
430 unsigned long addr, unsigned len);
431
432unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
433 const char *start, const char *end);
434
435unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
436 unsigned long addr, unsigned len);
437
438int paravirt_disable_iospace(void);
439
440/*
441 * This generates an indirect call based on the operation type number.
442 * The type number, computed in PARAVIRT_PATCH, is derived from the
443 * offset into the paravirt_patch_template structure, and can therefore be
444 * freely converted back into a structure offset.
445 */
446#define PARAVIRT_CALL "call *%c[paravirt_opptr];"
447
448/*
449 * These macros are intended to wrap calls through one of the paravirt
450 * ops structs, so that they can be later identified and patched at
451 * runtime.
452 *
453 * Normally, a call to a pv_op function is a simple indirect call:
454 * (pv_op_struct.operations)(args...).
455 *
456 * Unfortunately, this is a relatively slow operation for modern CPUs,
457 * because it cannot necessarily determine what the destination
458 * address is. In this case, the address is a runtime constant, so at
459 * the very least we can patch the call to e a simple direct call, or
460 * ideally, patch an inline implementation into the callsite. (Direct
461 * calls are essentially free, because the call and return addresses
462 * are completely predictable.)
463 *
464 * For i386, these macros rely on the standard gcc "regparm(3)" calling
465 * convention, in which the first three arguments are placed in %eax,
466 * %edx, %ecx (in that order), and the remaining arguments are placed
467 * on the stack. All caller-save registers (eax,edx,ecx) are expected
468 * to be modified (either clobbered or used for return values).
469 * X86_64, on the other hand, already specifies a register-based calling
470 * conventions, returning at %rax, with parameteres going on %rdi, %rsi,
471 * %rdx, and %rcx. Note that for this reason, x86_64 does not need any
472 * special handling for dealing with 4 arguments, unlike i386.
473 * However, x86_64 also have to clobber all caller saved registers, which
474 * unfortunately, are quite a bit (r8 - r11)
475 *
476 * The call instruction itself is marked by placing its start address
477 * and size into the .parainstructions section, so that
478 * apply_paravirt() in arch/i386/kernel/alternative.c can do the
479 * appropriate patching under the control of the backend pv_init_ops
480 * implementation.
481 *
482 * Unfortunately there's no way to get gcc to generate the args setup
483 * for the call, and then allow the call itself to be generated by an
484 * inline asm. Because of this, we must do the complete arg setup and
485 * return value handling from within these macros. This is fairly
486 * cumbersome.
487 *
488 * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments.
489 * It could be extended to more arguments, but there would be little
490 * to be gained from that. For each number of arguments, there are
491 * the two VCALL and CALL variants for void and non-void functions.
492 *
493 * When there is a return value, the invoker of the macro must specify
494 * the return type. The macro then uses sizeof() on that type to
495 * determine whether its a 32 or 64 bit value, and places the return
496 * in the right register(s) (just %eax for 32-bit, and %edx:%eax for
497 * 64-bit). For x86_64 machines, it just returns at %rax regardless of
498 * the return value size.
499 *
500 * 64-bit arguments are passed as a pair of adjacent 32-bit arguments
501 * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments
502 * in low,high order
503 *
504 * Small structures are passed and returned in registers. The macro
505 * calling convention can't directly deal with this, so the wrapper
506 * functions must do this.
507 *
508 * These PVOP_* macros are only defined within this header. This
509 * means that all uses must be wrapped in inline functions. This also
510 * makes sure the incoming and outgoing types are always correct.
511 */
512#ifdef CONFIG_X86_32
513#define PVOP_VCALL_ARGS \
514 unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx
515#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
516
517#define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x))
518#define PVOP_CALL_ARG2(x) "d" ((unsigned long)(x))
519#define PVOP_CALL_ARG3(x) "c" ((unsigned long)(x))
520
521#define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \
522 "=c" (__ecx)
523#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS
524
525#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx)
526#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
527
528#define EXTRA_CLOBBERS
529#define VEXTRA_CLOBBERS
530#else /* CONFIG_X86_64 */
531#define PVOP_VCALL_ARGS \
532 unsigned long __edi = __edi, __esi = __esi, \
533 __edx = __edx, __ecx = __ecx
534#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax
535
536#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x))
537#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x))
538#define PVOP_CALL_ARG3(x) "d" ((unsigned long)(x))
539#define PVOP_CALL_ARG4(x) "c" ((unsigned long)(x))
540
541#define PVOP_VCALL_CLOBBERS "=D" (__edi), \
542 "=S" (__esi), "=d" (__edx), \
543 "=c" (__ecx)
544#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
545
546#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
547#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
548
549#define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11"
550#define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11"
551#endif /* CONFIG_X86_32 */
552
553#ifdef CONFIG_PARAVIRT_DEBUG
554#define PVOP_TEST_NULL(op) BUG_ON(op == NULL)
555#else
556#define PVOP_TEST_NULL(op) ((void)op)
557#endif
558
559#define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr, \
560 pre, post, ...) \
561 ({ \
562 rettype __ret; \
563 PVOP_CALL_ARGS; \
564 PVOP_TEST_NULL(op); \
565 /* This is 32-bit specific, but is okay in 64-bit */ \
566 /* since this condition will never hold */ \
567 if (sizeof(rettype) > sizeof(unsigned long)) { \
568 asm volatile(pre \
569 paravirt_alt(PARAVIRT_CALL) \
570 post \
571 : call_clbr \
572 : paravirt_type(op), \
573 paravirt_clobber(clbr), \
574 ##__VA_ARGS__ \
575 : "memory", "cc" extra_clbr); \
576 __ret = (rettype)((((u64)__edx) << 32) | __eax); \
577 } else { \
578 asm volatile(pre \
579 paravirt_alt(PARAVIRT_CALL) \
580 post \
581 : call_clbr \
582 : paravirt_type(op), \
583 paravirt_clobber(clbr), \
584 ##__VA_ARGS__ \
585 : "memory", "cc" extra_clbr); \
586 __ret = (rettype)__eax; \
587 } \
588 __ret; \
589 })
590
591#define __PVOP_CALL(rettype, op, pre, post, ...) \
592 ____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS, \
593 EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__)
594
595#define __PVOP_CALLEESAVE(rettype, op, pre, post, ...) \
596 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
597 PVOP_CALLEE_CLOBBERS, , \
598 pre, post, ##__VA_ARGS__)
599
600
601#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...) \
602 ({ \
603 PVOP_VCALL_ARGS; \
604 PVOP_TEST_NULL(op); \
605 asm volatile(pre \
606 paravirt_alt(PARAVIRT_CALL) \
607 post \
608 : call_clbr \
609 : paravirt_type(op), \
610 paravirt_clobber(clbr), \
611 ##__VA_ARGS__ \
612 : "memory", "cc" extra_clbr); \
613 })
614
615#define __PVOP_VCALL(op, pre, post, ...) \
616 ____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS, \
617 VEXTRA_CLOBBERS, \
618 pre, post, ##__VA_ARGS__)
619
620#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \
621 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
622 PVOP_VCALLEE_CLOBBERS, , \
623 pre, post, ##__VA_ARGS__)
624
625
626
627#define PVOP_CALL0(rettype, op) \
628 __PVOP_CALL(rettype, op, "", "")
629#define PVOP_VCALL0(op) \
630 __PVOP_VCALL(op, "", "")
631
632#define PVOP_CALLEE0(rettype, op) \
633 __PVOP_CALLEESAVE(rettype, op, "", "")
634#define PVOP_VCALLEE0(op) \
635 __PVOP_VCALLEESAVE(op, "", "")
636
637
638#define PVOP_CALL1(rettype, op, arg1) \
639 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
640#define PVOP_VCALL1(op, arg1) \
641 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1))
642
643#define PVOP_CALLEE1(rettype, op, arg1) \
644 __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
645#define PVOP_VCALLEE1(op, arg1) \
646 __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1))
647
648
649#define PVOP_CALL2(rettype, op, arg1, arg2) \
650 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
651 PVOP_CALL_ARG2(arg2))
652#define PVOP_VCALL2(op, arg1, arg2) \
653 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \
654 PVOP_CALL_ARG2(arg2))
655
656#define PVOP_CALLEE2(rettype, op, arg1, arg2) \
657 __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
658 PVOP_CALL_ARG2(arg2))
659#define PVOP_VCALLEE2(op, arg1, arg2) \
660 __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1), \
661 PVOP_CALL_ARG2(arg2))
662
663
664#define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \
665 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
666 PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
667#define PVOP_VCALL3(op, arg1, arg2, arg3) \
668 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \
669 PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
670
671/* This is the only difference in x86_64. We can make it much simpler */
672#ifdef CONFIG_X86_32
673#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \
674 __PVOP_CALL(rettype, op, \
675 "push %[_arg4];", "lea 4(%%esp),%%esp;", \
676 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
677 PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4)))
678#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \
679 __PVOP_VCALL(op, \
680 "push %[_arg4];", "lea 4(%%esp),%%esp;", \
681 "0" ((u32)(arg1)), "1" ((u32)(arg2)), \
682 "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
683#else
684#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \
685 __PVOP_CALL(rettype, op, "", "", \
686 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
687 PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
688#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \
689 __PVOP_VCALL(op, "", "", \
690 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
691 PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
692#endif
693 15
694static inline int paravirt_enabled(void) 16static inline int paravirt_enabled(void)
695{ 17{
@@ -820,15 +142,22 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
820{ 142{
821 return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); 143 return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
822} 144}
823static inline u64 paravirt_read_msr_amd(unsigned msr, int *err) 145
146static inline int paravirt_rdmsr_regs(u32 *regs)
824{ 147{
825 return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err); 148 return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs);
826} 149}
150
827static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) 151static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
828{ 152{
829 return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); 153 return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
830} 154}
831 155
156static inline int paravirt_wrmsr_regs(u32 *regs)
157{
158 return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs);
159}
160
832/* These should all do BUG_ON(_err), but our headers are too tangled. */ 161/* These should all do BUG_ON(_err), but our headers are too tangled. */
833#define rdmsr(msr, val1, val2) \ 162#define rdmsr(msr, val1, val2) \
834do { \ 163do { \
@@ -862,6 +191,9 @@ do { \
862 _err; \ 191 _err; \
863}) 192})
864 193
194#define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs)
195#define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs)
196
865static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) 197static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
866{ 198{
867 int err; 199 int err;
@@ -871,12 +203,31 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
871} 203}
872static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) 204static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
873{ 205{
206 u32 gprs[8] = { 0 };
874 int err; 207 int err;
875 208
876 *p = paravirt_read_msr_amd(msr, &err); 209 gprs[1] = msr;
210 gprs[7] = 0x9c5a203a;
211
212 err = paravirt_rdmsr_regs(gprs);
213
214 *p = gprs[0] | ((u64)gprs[2] << 32);
215
877 return err; 216 return err;
878} 217}
879 218
219static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
220{
221 u32 gprs[8] = { 0 };
222
223 gprs[0] = (u32)val;
224 gprs[1] = msr;
225 gprs[2] = val >> 32;
226 gprs[7] = 0x9c5a203a;
227
228 return paravirt_wrmsr_regs(gprs);
229}
230
880static inline u64 paravirt_read_tsc(void) 231static inline u64 paravirt_read_tsc(void)
881{ 232{
882 return PVOP_CALL0(u64, pv_cpu_ops.read_tsc); 233 return PVOP_CALL0(u64, pv_cpu_ops.read_tsc);
@@ -1393,20 +744,6 @@ static inline void pmd_clear(pmd_t *pmdp)
1393} 744}
1394#endif /* CONFIG_X86_PAE */ 745#endif /* CONFIG_X86_PAE */
1395 746
1396/* Lazy mode for batching updates / context switch */
1397enum paravirt_lazy_mode {
1398 PARAVIRT_LAZY_NONE,
1399 PARAVIRT_LAZY_MMU,
1400 PARAVIRT_LAZY_CPU,
1401};
1402
1403enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
1404void paravirt_start_context_switch(struct task_struct *prev);
1405void paravirt_end_context_switch(struct task_struct *next);
1406
1407void paravirt_enter_lazy_mmu(void);
1408void paravirt_leave_lazy_mmu(void);
1409
1410#define __HAVE_ARCH_START_CONTEXT_SWITCH 747#define __HAVE_ARCH_START_CONTEXT_SWITCH
1411static inline void arch_start_context_switch(struct task_struct *prev) 748static inline void arch_start_context_switch(struct task_struct *prev)
1412{ 749{
@@ -1437,12 +774,6 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
1437 pv_mmu_ops.set_fixmap(idx, phys, flags); 774 pv_mmu_ops.set_fixmap(idx, phys, flags);
1438} 775}
1439 776
1440void _paravirt_nop(void);
1441u32 _paravirt_ident_32(u32);
1442u64 _paravirt_ident_64(u64);
1443
1444#define paravirt_nop ((void *)_paravirt_nop)
1445
1446#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) 777#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
1447 778
1448static inline int __raw_spin_is_locked(struct raw_spinlock *lock) 779static inline int __raw_spin_is_locked(struct raw_spinlock *lock)
@@ -1479,17 +810,6 @@ static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
1479 810
1480#endif 811#endif
1481 812
1482/* These all sit in the .parainstructions section to tell us what to patch. */
1483struct paravirt_patch_site {
1484 u8 *instr; /* original instructions */
1485 u8 instrtype; /* type of this instruction */
1486 u8 len; /* length of original instruction */
1487 u16 clobbers; /* what registers you may clobber */
1488};
1489
1490extern struct paravirt_patch_site __parainstructions[],
1491 __parainstructions_end[];
1492
1493#ifdef CONFIG_X86_32 813#ifdef CONFIG_X86_32
1494#define PV_SAVE_REGS "pushl %ecx; pushl %edx;" 814#define PV_SAVE_REGS "pushl %ecx; pushl %edx;"
1495#define PV_RESTORE_REGS "popl %edx; popl %ecx;" 815#define PV_RESTORE_REGS "popl %edx; popl %ecx;"
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
new file mode 100644
index 000000000000..25402d0006e7
--- /dev/null
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -0,0 +1,721 @@
1#ifndef _ASM_X86_PARAVIRT_TYPES_H
2#define _ASM_X86_PARAVIRT_TYPES_H
3
4/* Bitmask of what can be clobbered: usually at least eax. */
5#define CLBR_NONE 0
6#define CLBR_EAX (1 << 0)
7#define CLBR_ECX (1 << 1)
8#define CLBR_EDX (1 << 2)
9#define CLBR_EDI (1 << 3)
10
11#ifdef CONFIG_X86_32
12/* CLBR_ANY should match all regs platform has. For i386, that's just it */
13#define CLBR_ANY ((1 << 4) - 1)
14
15#define CLBR_ARG_REGS (CLBR_EAX | CLBR_EDX | CLBR_ECX)
16#define CLBR_RET_REG (CLBR_EAX | CLBR_EDX)
17#define CLBR_SCRATCH (0)
18#else
19#define CLBR_RAX CLBR_EAX
20#define CLBR_RCX CLBR_ECX
21#define CLBR_RDX CLBR_EDX
22#define CLBR_RDI CLBR_EDI
23#define CLBR_RSI (1 << 4)
24#define CLBR_R8 (1 << 5)
25#define CLBR_R9 (1 << 6)
26#define CLBR_R10 (1 << 7)
27#define CLBR_R11 (1 << 8)
28
29#define CLBR_ANY ((1 << 9) - 1)
30
31#define CLBR_ARG_REGS (CLBR_RDI | CLBR_RSI | CLBR_RDX | \
32 CLBR_RCX | CLBR_R8 | CLBR_R9)
33#define CLBR_RET_REG (CLBR_RAX)
34#define CLBR_SCRATCH (CLBR_R10 | CLBR_R11)
35
36#endif /* X86_64 */
37
38#define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG)
39
40#ifndef __ASSEMBLY__
41
42#include <asm/desc_defs.h>
43#include <asm/kmap_types.h>
44
45struct page;
46struct thread_struct;
47struct desc_ptr;
48struct tss_struct;
49struct mm_struct;
50struct desc_struct;
51struct task_struct;
52struct cpumask;
53
54/*
55 * Wrapper type for pointers to code which uses the non-standard
56 * calling convention. See PV_CALL_SAVE_REGS_THUNK below.
57 */
58struct paravirt_callee_save {
59 void *func;
60};
61
62/* general info */
63struct pv_info {
64 unsigned int kernel_rpl;
65 int shared_kernel_pmd;
66 int paravirt_enabled;
67 const char *name;
68};
69
70struct pv_init_ops {
71 /*
72 * Patch may replace one of the defined code sequences with
73 * arbitrary code, subject to the same register constraints.
74 * This generally means the code is not free to clobber any
75 * registers other than EAX. The patch function should return
76 * the number of bytes of code generated, as we nop pad the
77 * rest in generic code.
78 */
79 unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
80 unsigned long addr, unsigned len);
81
82 /* Basic arch-specific setup */
83 void (*arch_setup)(void);
84 char *(*memory_setup)(void);
85 void (*post_allocator_init)(void);
86
87 /* Print a banner to identify the environment */
88 void (*banner)(void);
89};
90
91
92struct pv_lazy_ops {
93 /* Set deferred update mode, used for batching operations. */
94 void (*enter)(void);
95 void (*leave)(void);
96};
97
98struct pv_time_ops {
99 void (*time_init)(void);
100
101 /* Set and set time of day */
102 unsigned long (*get_wallclock)(void);
103 int (*set_wallclock)(unsigned long);
104
105 unsigned long long (*sched_clock)(void);
106 unsigned long (*get_tsc_khz)(void);
107};
108
109struct pv_cpu_ops {
110 /* hooks for various privileged instructions */
111 unsigned long (*get_debugreg)(int regno);
112 void (*set_debugreg)(int regno, unsigned long value);
113
114 void (*clts)(void);
115
116 unsigned long (*read_cr0)(void);
117 void (*write_cr0)(unsigned long);
118
119 unsigned long (*read_cr4_safe)(void);
120 unsigned long (*read_cr4)(void);
121 void (*write_cr4)(unsigned long);
122
123#ifdef CONFIG_X86_64
124 unsigned long (*read_cr8)(void);
125 void (*write_cr8)(unsigned long);
126#endif
127
128 /* Segment descriptor handling */
129 void (*load_tr_desc)(void);
130 void (*load_gdt)(const struct desc_ptr *);
131 void (*load_idt)(const struct desc_ptr *);
132 void (*store_gdt)(struct desc_ptr *);
133 void (*store_idt)(struct desc_ptr *);
134 void (*set_ldt)(const void *desc, unsigned entries);
135 unsigned long (*store_tr)(void);
136 void (*load_tls)(struct thread_struct *t, unsigned int cpu);
137#ifdef CONFIG_X86_64
138 void (*load_gs_index)(unsigned int idx);
139#endif
140 void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum,
141 const void *desc);
142 void (*write_gdt_entry)(struct desc_struct *,
143 int entrynum, const void *desc, int size);
144 void (*write_idt_entry)(gate_desc *,
145 int entrynum, const gate_desc *gate);
146 void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries);
147 void (*free_ldt)(struct desc_struct *ldt, unsigned entries);
148
149 void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
150
151 void (*set_iopl_mask)(unsigned mask);
152
153 void (*wbinvd)(void);
154 void (*io_delay)(void);
155
156 /* cpuid emulation, mostly so that caps bits can be disabled */
157 void (*cpuid)(unsigned int *eax, unsigned int *ebx,
158 unsigned int *ecx, unsigned int *edx);
159
160 /* MSR, PMC and TSR operations.
161 err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
162 u64 (*read_msr)(unsigned int msr, int *err);
163 int (*rdmsr_regs)(u32 *regs);
164 int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
165 int (*wrmsr_regs)(u32 *regs);
166
167 u64 (*read_tsc)(void);
168 u64 (*read_pmc)(int counter);
169 unsigned long long (*read_tscp)(unsigned int *aux);
170
171 /*
172 * Atomically enable interrupts and return to userspace. This
173 * is only ever used to return to 32-bit processes; in a
174 * 64-bit kernel, it's used for 32-on-64 compat processes, but
175 * never native 64-bit processes. (Jump, not call.)
176 */
177 void (*irq_enable_sysexit)(void);
178
179 /*
180 * Switch to usermode gs and return to 64-bit usermode using
181 * sysret. Only used in 64-bit kernels to return to 64-bit
182 * processes. Usermode register state, including %rsp, must
183 * already be restored.
184 */
185 void (*usergs_sysret64)(void);
186
187 /*
188 * Switch to usermode gs and return to 32-bit usermode using
189 * sysret. Used to return to 32-on-64 compat processes.
190 * Other usermode register state, including %esp, must already
191 * be restored.
192 */
193 void (*usergs_sysret32)(void);
194
195 /* Normal iret. Jump to this with the standard iret stack
196 frame set up. */
197 void (*iret)(void);
198
199 void (*swapgs)(void);
200
201 void (*start_context_switch)(struct task_struct *prev);
202 void (*end_context_switch)(struct task_struct *next);
203};
204
205struct pv_irq_ops {
206 void (*init_IRQ)(void);
207
208 /*
209 * Get/set interrupt state. save_fl and restore_fl are only
210 * expected to use X86_EFLAGS_IF; all other bits
211 * returned from save_fl are undefined, and may be ignored by
212 * restore_fl.
213 *
214 * NOTE: These functions callers expect the callee to preserve
215 * more registers than the standard C calling convention.
216 */
217 struct paravirt_callee_save save_fl;
218 struct paravirt_callee_save restore_fl;
219 struct paravirt_callee_save irq_disable;
220 struct paravirt_callee_save irq_enable;
221
222 void (*safe_halt)(void);
223 void (*halt)(void);
224
225#ifdef CONFIG_X86_64
226 void (*adjust_exception_frame)(void);
227#endif
228};
229
230struct pv_apic_ops {
231#ifdef CONFIG_X86_LOCAL_APIC
232 void (*setup_boot_clock)(void);
233 void (*setup_secondary_clock)(void);
234
235 void (*startup_ipi_hook)(int phys_apicid,
236 unsigned long start_eip,
237 unsigned long start_esp);
238#endif
239};
240
241struct pv_mmu_ops {
242 /*
243 * Called before/after init_mm pagetable setup. setup_start
244 * may reset %cr3, and may pre-install parts of the pagetable;
245 * pagetable setup is expected to preserve any existing
246 * mapping.
247 */
248 void (*pagetable_setup_start)(pgd_t *pgd_base);
249 void (*pagetable_setup_done)(pgd_t *pgd_base);
250
251 unsigned long (*read_cr2)(void);
252 void (*write_cr2)(unsigned long);
253
254 unsigned long (*read_cr3)(void);
255 void (*write_cr3)(unsigned long);
256
257 /*
258 * Hooks for intercepting the creation/use/destruction of an
259 * mm_struct.
260 */
261 void (*activate_mm)(struct mm_struct *prev,
262 struct mm_struct *next);
263 void (*dup_mmap)(struct mm_struct *oldmm,
264 struct mm_struct *mm);
265 void (*exit_mmap)(struct mm_struct *mm);
266
267
268 /* TLB operations */
269 void (*flush_tlb_user)(void);
270 void (*flush_tlb_kernel)(void);
271 void (*flush_tlb_single)(unsigned long addr);
272 void (*flush_tlb_others)(const struct cpumask *cpus,
273 struct mm_struct *mm,
274 unsigned long va);
275
276 /* Hooks for allocating and freeing a pagetable top-level */
277 int (*pgd_alloc)(struct mm_struct *mm);
278 void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd);
279
280 /*
281 * Hooks for allocating/releasing pagetable pages when they're
282 * attached to a pagetable
283 */
284 void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
285 void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
286 void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
287 void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
288 void (*release_pte)(unsigned long pfn);
289 void (*release_pmd)(unsigned long pfn);
290 void (*release_pud)(unsigned long pfn);
291
292 /* Pagetable manipulation functions */
293 void (*set_pte)(pte_t *ptep, pte_t pteval);
294 void (*set_pte_at)(struct mm_struct *mm, unsigned long addr,
295 pte_t *ptep, pte_t pteval);
296 void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
297 void (*pte_update)(struct mm_struct *mm, unsigned long addr,
298 pte_t *ptep);
299 void (*pte_update_defer)(struct mm_struct *mm,
300 unsigned long addr, pte_t *ptep);
301
302 pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
303 pte_t *ptep);
304 void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
305 pte_t *ptep, pte_t pte);
306
307 struct paravirt_callee_save pte_val;
308 struct paravirt_callee_save make_pte;
309
310 struct paravirt_callee_save pgd_val;
311 struct paravirt_callee_save make_pgd;
312
313#if PAGETABLE_LEVELS >= 3
314#ifdef CONFIG_X86_PAE
315 void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
316 void (*pte_clear)(struct mm_struct *mm, unsigned long addr,
317 pte_t *ptep);
318 void (*pmd_clear)(pmd_t *pmdp);
319
320#endif /* CONFIG_X86_PAE */
321
322 void (*set_pud)(pud_t *pudp, pud_t pudval);
323
324 struct paravirt_callee_save pmd_val;
325 struct paravirt_callee_save make_pmd;
326
327#if PAGETABLE_LEVELS == 4
328 struct paravirt_callee_save pud_val;
329 struct paravirt_callee_save make_pud;
330
331 void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
332#endif /* PAGETABLE_LEVELS == 4 */
333#endif /* PAGETABLE_LEVELS >= 3 */
334
335#ifdef CONFIG_HIGHPTE
336 void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
337#endif
338
339 struct pv_lazy_ops lazy_mode;
340
341 /* dom0 ops */
342
343 /* Sometimes the physical address is a pfn, and sometimes its
344 an mfn. We can tell which is which from the index. */
345 void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
346 phys_addr_t phys, pgprot_t flags);
347};
348
349struct raw_spinlock;
350struct pv_lock_ops {
351 int (*spin_is_locked)(struct raw_spinlock *lock);
352 int (*spin_is_contended)(struct raw_spinlock *lock);
353 void (*spin_lock)(struct raw_spinlock *lock);
354 void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags);
355 int (*spin_trylock)(struct raw_spinlock *lock);
356 void (*spin_unlock)(struct raw_spinlock *lock);
357};
358
359/* This contains all the paravirt structures: we get a convenient
360 * number for each function using the offset which we use to indicate
361 * what to patch. */
362struct paravirt_patch_template {
363 struct pv_init_ops pv_init_ops;
364 struct pv_time_ops pv_time_ops;
365 struct pv_cpu_ops pv_cpu_ops;
366 struct pv_irq_ops pv_irq_ops;
367 struct pv_apic_ops pv_apic_ops;
368 struct pv_mmu_ops pv_mmu_ops;
369 struct pv_lock_ops pv_lock_ops;
370};
371
372extern struct pv_info pv_info;
373extern struct pv_init_ops pv_init_ops;
374extern struct pv_time_ops pv_time_ops;
375extern struct pv_cpu_ops pv_cpu_ops;
376extern struct pv_irq_ops pv_irq_ops;
377extern struct pv_apic_ops pv_apic_ops;
378extern struct pv_mmu_ops pv_mmu_ops;
379extern struct pv_lock_ops pv_lock_ops;
380
381#define PARAVIRT_PATCH(x) \
382 (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
383
384#define paravirt_type(op) \
385 [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \
386 [paravirt_opptr] "i" (&(op))
387#define paravirt_clobber(clobber) \
388 [paravirt_clobber] "i" (clobber)
389
390/*
391 * Generate some code, and mark it as patchable by the
392 * apply_paravirt() alternate instruction patcher.
393 */
394#define _paravirt_alt(insn_string, type, clobber) \
395 "771:\n\t" insn_string "\n" "772:\n" \
396 ".pushsection .parainstructions,\"a\"\n" \
397 _ASM_ALIGN "\n" \
398 _ASM_PTR " 771b\n" \
399 " .byte " type "\n" \
400 " .byte 772b-771b\n" \
401 " .short " clobber "\n" \
402 ".popsection\n"
403
404/* Generate patchable code, with the default asm parameters. */
405#define paravirt_alt(insn_string) \
406 _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
407
408/* Simple instruction patching code. */
409#define DEF_NATIVE(ops, name, code) \
410 extern const char start_##ops##_##name[], end_##ops##_##name[]; \
411 asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
412
413unsigned paravirt_patch_nop(void);
414unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
415unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
416unsigned paravirt_patch_ignore(unsigned len);
417unsigned paravirt_patch_call(void *insnbuf,
418 const void *target, u16 tgt_clobbers,
419 unsigned long addr, u16 site_clobbers,
420 unsigned len);
421unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
422 unsigned long addr, unsigned len);
423unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
424 unsigned long addr, unsigned len);
425
426unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
427 const char *start, const char *end);
428
429unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
430 unsigned long addr, unsigned len);
431
432int paravirt_disable_iospace(void);
433
434/*
435 * This generates an indirect call based on the operation type number.
436 * The type number, computed in PARAVIRT_PATCH, is derived from the
437 * offset into the paravirt_patch_template structure, and can therefore be
438 * freely converted back into a structure offset.
439 */
440#define PARAVIRT_CALL "call *%c[paravirt_opptr];"
441
442/*
443 * These macros are intended to wrap calls through one of the paravirt
444 * ops structs, so that they can be later identified and patched at
445 * runtime.
446 *
447 * Normally, a call to a pv_op function is a simple indirect call:
448 * (pv_op_struct.operations)(args...).
449 *
450 * Unfortunately, this is a relatively slow operation for modern CPUs,
451 * because it cannot necessarily determine what the destination
452 * address is. In this case, the address is a runtime constant, so at
453 * the very least we can patch the call to e a simple direct call, or
454 * ideally, patch an inline implementation into the callsite. (Direct
455 * calls are essentially free, because the call and return addresses
456 * are completely predictable.)
457 *
458 * For i386, these macros rely on the standard gcc "regparm(3)" calling
459 * convention, in which the first three arguments are placed in %eax,
460 * %edx, %ecx (in that order), and the remaining arguments are placed
461 * on the stack. All caller-save registers (eax,edx,ecx) are expected
462 * to be modified (either clobbered or used for return values).
463 * X86_64, on the other hand, already specifies a register-based calling
464 * conventions, returning at %rax, with parameteres going on %rdi, %rsi,
465 * %rdx, and %rcx. Note that for this reason, x86_64 does not need any
466 * special handling for dealing with 4 arguments, unlike i386.
467 * However, x86_64 also have to clobber all caller saved registers, which
468 * unfortunately, are quite a bit (r8 - r11)
469 *
470 * The call instruction itself is marked by placing its start address
471 * and size into the .parainstructions section, so that
472 * apply_paravirt() in arch/i386/kernel/alternative.c can do the
473 * appropriate patching under the control of the backend pv_init_ops
474 * implementation.
475 *
476 * Unfortunately there's no way to get gcc to generate the args setup
477 * for the call, and then allow the call itself to be generated by an
478 * inline asm. Because of this, we must do the complete arg setup and
479 * return value handling from within these macros. This is fairly
480 * cumbersome.
481 *
482 * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments.
483 * It could be extended to more arguments, but there would be little
484 * to be gained from that. For each number of arguments, there are
485 * the two VCALL and CALL variants for void and non-void functions.
486 *
487 * When there is a return value, the invoker of the macro must specify
488 * the return type. The macro then uses sizeof() on that type to
489 * determine whether its a 32 or 64 bit value, and places the return
490 * in the right register(s) (just %eax for 32-bit, and %edx:%eax for
491 * 64-bit). For x86_64 machines, it just returns at %rax regardless of
492 * the return value size.
493 *
494 * 64-bit arguments are passed as a pair of adjacent 32-bit arguments
495 * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments
496 * in low,high order
497 *
498 * Small structures are passed and returned in registers. The macro
499 * calling convention can't directly deal with this, so the wrapper
500 * functions must do this.
501 *
502 * These PVOP_* macros are only defined within this header. This
503 * means that all uses must be wrapped in inline functions. This also
504 * makes sure the incoming and outgoing types are always correct.
505 */
506#ifdef CONFIG_X86_32
507#define PVOP_VCALL_ARGS \
508 unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx
509#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
510
511#define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x))
512#define PVOP_CALL_ARG2(x) "d" ((unsigned long)(x))
513#define PVOP_CALL_ARG3(x) "c" ((unsigned long)(x))
514
515#define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \
516 "=c" (__ecx)
517#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS
518
519#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx)
520#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
521
522#define EXTRA_CLOBBERS
523#define VEXTRA_CLOBBERS
524#else /* CONFIG_X86_64 */
525#define PVOP_VCALL_ARGS \
526 unsigned long __edi = __edi, __esi = __esi, \
527 __edx = __edx, __ecx = __ecx
528#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax
529
530#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x))
531#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x))
532#define PVOP_CALL_ARG3(x) "d" ((unsigned long)(x))
533#define PVOP_CALL_ARG4(x) "c" ((unsigned long)(x))
534
535#define PVOP_VCALL_CLOBBERS "=D" (__edi), \
536 "=S" (__esi), "=d" (__edx), \
537 "=c" (__ecx)
538#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
539
540#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
541#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
542
543#define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11"
544#define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11"
545#endif /* CONFIG_X86_32 */
546
547#ifdef CONFIG_PARAVIRT_DEBUG
548#define PVOP_TEST_NULL(op) BUG_ON(op == NULL)
549#else
550#define PVOP_TEST_NULL(op) ((void)op)
551#endif
552
553#define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr, \
554 pre, post, ...) \
555 ({ \
556 rettype __ret; \
557 PVOP_CALL_ARGS; \
558 PVOP_TEST_NULL(op); \
559 /* This is 32-bit specific, but is okay in 64-bit */ \
560 /* since this condition will never hold */ \
561 if (sizeof(rettype) > sizeof(unsigned long)) { \
562 asm volatile(pre \
563 paravirt_alt(PARAVIRT_CALL) \
564 post \
565 : call_clbr \
566 : paravirt_type(op), \
567 paravirt_clobber(clbr), \
568 ##__VA_ARGS__ \
569 : "memory", "cc" extra_clbr); \
570 __ret = (rettype)((((u64)__edx) << 32) | __eax); \
571 } else { \
572 asm volatile(pre \
573 paravirt_alt(PARAVIRT_CALL) \
574 post \
575 : call_clbr \
576 : paravirt_type(op), \
577 paravirt_clobber(clbr), \
578 ##__VA_ARGS__ \
579 : "memory", "cc" extra_clbr); \
580 __ret = (rettype)__eax; \
581 } \
582 __ret; \
583 })
584
585#define __PVOP_CALL(rettype, op, pre, post, ...) \
586 ____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS, \
587 EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__)
588
589#define __PVOP_CALLEESAVE(rettype, op, pre, post, ...) \
590 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
591 PVOP_CALLEE_CLOBBERS, , \
592 pre, post, ##__VA_ARGS__)
593
594
595#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...) \
596 ({ \
597 PVOP_VCALL_ARGS; \
598 PVOP_TEST_NULL(op); \
599 asm volatile(pre \
600 paravirt_alt(PARAVIRT_CALL) \
601 post \
602 : call_clbr \
603 : paravirt_type(op), \
604 paravirt_clobber(clbr), \
605 ##__VA_ARGS__ \
606 : "memory", "cc" extra_clbr); \
607 })
608
609#define __PVOP_VCALL(op, pre, post, ...) \
610 ____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS, \
611 VEXTRA_CLOBBERS, \
612 pre, post, ##__VA_ARGS__)
613
614#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \
615 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \
616 PVOP_VCALLEE_CLOBBERS, , \
617 pre, post, ##__VA_ARGS__)
618
619
620
621#define PVOP_CALL0(rettype, op) \
622 __PVOP_CALL(rettype, op, "", "")
623#define PVOP_VCALL0(op) \
624 __PVOP_VCALL(op, "", "")
625
626#define PVOP_CALLEE0(rettype, op) \
627 __PVOP_CALLEESAVE(rettype, op, "", "")
628#define PVOP_VCALLEE0(op) \
629 __PVOP_VCALLEESAVE(op, "", "")
630
631
632#define PVOP_CALL1(rettype, op, arg1) \
633 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
634#define PVOP_VCALL1(op, arg1) \
635 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1))
636
637#define PVOP_CALLEE1(rettype, op, arg1) \
638 __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
639#define PVOP_VCALLEE1(op, arg1) \
640 __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1))
641
642
643#define PVOP_CALL2(rettype, op, arg1, arg2) \
644 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
645 PVOP_CALL_ARG2(arg2))
646#define PVOP_VCALL2(op, arg1, arg2) \
647 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \
648 PVOP_CALL_ARG2(arg2))
649
650#define PVOP_CALLEE2(rettype, op, arg1, arg2) \
651 __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
652 PVOP_CALL_ARG2(arg2))
653#define PVOP_VCALLEE2(op, arg1, arg2) \
654 __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1), \
655 PVOP_CALL_ARG2(arg2))
656
657
658#define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \
659 __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
660 PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
661#define PVOP_VCALL3(op, arg1, arg2, arg3) \
662 __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \
663 PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
664
665/* This is the only difference in x86_64. We can make it much simpler */
666#ifdef CONFIG_X86_32
667#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \
668 __PVOP_CALL(rettype, op, \
669 "push %[_arg4];", "lea 4(%%esp),%%esp;", \
670 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
671 PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4)))
672#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \
673 __PVOP_VCALL(op, \
674 "push %[_arg4];", "lea 4(%%esp),%%esp;", \
675 "0" ((u32)(arg1)), "1" ((u32)(arg2)), \
676 "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
677#else
678#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \
679 __PVOP_CALL(rettype, op, "", "", \
680 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
681 PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
682#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \
683 __PVOP_VCALL(op, "", "", \
684 PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \
685 PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
686#endif
687
688/* Lazy mode for batching updates / context switch */
689enum paravirt_lazy_mode {
690 PARAVIRT_LAZY_NONE,
691 PARAVIRT_LAZY_MMU,
692 PARAVIRT_LAZY_CPU,
693};
694
695enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
696void paravirt_start_context_switch(struct task_struct *prev);
697void paravirt_end_context_switch(struct task_struct *next);
698
699void paravirt_enter_lazy_mmu(void);
700void paravirt_leave_lazy_mmu(void);
701
702void _paravirt_nop(void);
703u32 _paravirt_ident_32(u32);
704u64 _paravirt_ident_64(u64);
705
706#define paravirt_nop ((void *)_paravirt_nop)
707
708/* These all sit in the .parainstructions section to tell us what to patch. */
709struct paravirt_patch_site {
710 u8 *instr; /* original instructions */
711 u8 instrtype; /* type of this instruction */
712 u8 len; /* length of original instruction */
713 u16 clobbers; /* what registers you may clobber */
714};
715
716extern struct paravirt_patch_site __parainstructions[],
717 __parainstructions_end[];
718
719#endif /* __ASSEMBLY__ */
720
721#endif /* _ASM_X86_PARAVIRT_TYPES_H */
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 103f1ddb0d85..04eacefcfd26 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -49,7 +49,7 @@
49#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x 49#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x
50#define __my_cpu_offset percpu_read(this_cpu_off) 50#define __my_cpu_offset percpu_read(this_cpu_off)
51#else 51#else
52#define __percpu_arg(x) "%" #x 52#define __percpu_arg(x) "%P" #x
53#endif 53#endif
54 54
55/* 55/*
@@ -104,36 +104,48 @@ do { \
104 } \ 104 } \
105} while (0) 105} while (0)
106 106
107#define percpu_from_op(op, var) \ 107#define percpu_from_op(op, var, constraint) \
108({ \ 108({ \
109 typeof(var) ret__; \ 109 typeof(var) ret__; \
110 switch (sizeof(var)) { \ 110 switch (sizeof(var)) { \
111 case 1: \ 111 case 1: \
112 asm(op "b "__percpu_arg(1)",%0" \ 112 asm(op "b "__percpu_arg(1)",%0" \
113 : "=q" (ret__) \ 113 : "=q" (ret__) \
114 : "m" (var)); \ 114 : constraint); \
115 break; \ 115 break; \
116 case 2: \ 116 case 2: \
117 asm(op "w "__percpu_arg(1)",%0" \ 117 asm(op "w "__percpu_arg(1)",%0" \
118 : "=r" (ret__) \ 118 : "=r" (ret__) \
119 : "m" (var)); \ 119 : constraint); \
120 break; \ 120 break; \
121 case 4: \ 121 case 4: \
122 asm(op "l "__percpu_arg(1)",%0" \ 122 asm(op "l "__percpu_arg(1)",%0" \
123 : "=r" (ret__) \ 123 : "=r" (ret__) \
124 : "m" (var)); \ 124 : constraint); \
125 break; \ 125 break; \
126 case 8: \ 126 case 8: \
127 asm(op "q "__percpu_arg(1)",%0" \ 127 asm(op "q "__percpu_arg(1)",%0" \
128 : "=r" (ret__) \ 128 : "=r" (ret__) \
129 : "m" (var)); \ 129 : constraint); \
130 break; \ 130 break; \
131 default: __bad_percpu_size(); \ 131 default: __bad_percpu_size(); \
132 } \ 132 } \
133 ret__; \ 133 ret__; \
134}) 134})
135 135
136#define percpu_read(var) percpu_from_op("mov", per_cpu__##var) 136/*
137 * percpu_read() makes gcc load the percpu variable every time it is
138 * accessed while percpu_read_stable() allows the value to be cached.
139 * percpu_read_stable() is more efficient and can be used if its value
140 * is guaranteed to be valid across cpus. The current users include
141 * get_current() and get_thread_info() both of which are actually
142 * per-thread variables implemented as per-cpu variables and thus
143 * stable for the duration of the respective task.
144 */
145#define percpu_read(var) percpu_from_op("mov", per_cpu__##var, \
146 "m" (per_cpu__##var))
147#define percpu_read_stable(var) percpu_from_op("mov", per_cpu__##var, \
148 "p" (&per_cpu__##var))
137#define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val) 149#define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val)
138#define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val) 150#define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val)
139#define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val) 151#define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val)
diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h
index fa64e401589d..e7b7c938ae27 100644
--- a/arch/x86/include/asm/perf_counter.h
+++ b/arch/x86/include/asm/perf_counter.h
@@ -84,6 +84,16 @@ union cpuid10_edx {
84#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b 84#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b
85#define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) 85#define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2)
86 86
87/*
88 * We model BTS tracing as another fixed-mode PMC.
89 *
90 * We choose a value in the middle of the fixed counter range, since lower
91 * values are used by actual fixed counters and higher values are used
92 * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr.
93 */
94#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16)
95
96
87#ifdef CONFIG_PERF_COUNTERS 97#ifdef CONFIG_PERF_COUNTERS
88extern void init_hw_perf_counters(void); 98extern void init_hw_perf_counters(void);
89extern void perf_counters_lapic_init(void); 99extern void perf_counters_lapic_init(void);
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 16748077559a..4c5b51fdc788 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -135,6 +135,11 @@ static inline unsigned long pte_pfn(pte_t pte)
135 return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT; 135 return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
136} 136}
137 137
138static inline unsigned long pmd_pfn(pmd_t pmd)
139{
140 return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
141}
142
138#define pte_page(pte) pfn_to_page(pte_pfn(pte)) 143#define pte_page(pte) pfn_to_page(pte_pfn(pte))
139 144
140static inline int pmd_large(pmd_t pte) 145static inline int pmd_large(pmd_t pte)
@@ -359,7 +364,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
359 * this macro returns the index of the entry in the pmd page which would 364 * this macro returns the index of the entry in the pmd page which would
360 * control the given virtual address 365 * control the given virtual address
361 */ 366 */
362static inline unsigned pmd_index(unsigned long address) 367static inline unsigned long pmd_index(unsigned long address)
363{ 368{
364 return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); 369 return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
365} 370}
@@ -379,7 +384,7 @@ static inline unsigned pmd_index(unsigned long address)
379 * this function returns the index of the entry in the pte page which would 384 * this function returns the index of the entry in the pte page which would
380 * control the given virtual address 385 * control the given virtual address
381 */ 386 */
382static inline unsigned pte_index(unsigned long address) 387static inline unsigned long pte_index(unsigned long address)
383{ 388{
384 return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); 389 return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
385} 390}
@@ -430,11 +435,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
430 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); 435 return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
431} 436}
432 437
433static inline unsigned long pmd_pfn(pmd_t pmd)
434{
435 return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
436}
437
438static inline int pud_large(pud_t pud) 438static inline int pud_large(pud_t pud)
439{ 439{
440 return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == 440 return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
@@ -470,7 +470,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
470#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) 470#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
471 471
472/* to find an entry in a page-table-directory. */ 472/* to find an entry in a page-table-directory. */
473static inline unsigned pud_index(unsigned long address) 473static inline unsigned long pud_index(unsigned long address)
474{ 474{
475 return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1); 475 return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
476} 476}
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2b03f700d3f2..1153037ae9ff 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -404,7 +404,17 @@ extern unsigned long kernel_eflags;
404extern asmlinkage void ignore_sysret(void); 404extern asmlinkage void ignore_sysret(void);
405#else /* X86_64 */ 405#else /* X86_64 */
406#ifdef CONFIG_CC_STACKPROTECTOR 406#ifdef CONFIG_CC_STACKPROTECTOR
407DECLARE_PER_CPU(unsigned long, stack_canary); 407/*
408 * Make sure stack canary segment base is cached-aligned:
409 * "For Intel Atom processors, avoid non zero segment base address
410 * that is not aligned to cache line boundary at all cost."
411 * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
412 */
413struct stack_canary {
414 char __pad[20]; /* canary at %gs:20 */
415 unsigned long canary;
416};
417DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
408#endif 418#endif
409#endif /* X86_64 */ 419#endif /* X86_64 */
410 420
@@ -703,13 +713,23 @@ static inline void cpu_relax(void)
703 rep_nop(); 713 rep_nop();
704} 714}
705 715
706/* Stop speculative execution: */ 716/* Stop speculative execution and prefetching of modified code. */
707static inline void sync_core(void) 717static inline void sync_core(void)
708{ 718{
709 int tmp; 719 int tmp;
710 720
711 asm volatile("cpuid" : "=a" (tmp) : "0" (1) 721#if defined(CONFIG_M386) || defined(CONFIG_M486)
712 : "ebx", "ecx", "edx", "memory"); 722 if (boot_cpu_data.x86 < 5)
723 /* There is no speculative execution.
724 * jmp is a barrier to prefetching. */
725 asm volatile("jmp 1f\n1:\n" ::: "memory");
726 else
727#endif
728 /* cpuid is a barrier to speculative execution.
729 * Prefetched instructions are automatically
730 * invalidated when modified. */
731 asm volatile("cpuid" : "=a" (tmp) : "0" (1)
732 : "ebx", "ecx", "edx", "memory");
713} 733}
714 734
715static inline void __monitor(const void *eax, unsigned long ecx, 735static inline void __monitor(const void *eax, unsigned long ecx,
diff --git a/arch/x86/include/asm/scatterlist.h b/arch/x86/include/asm/scatterlist.h
index 263d397d2eef..75af592677ec 100644
--- a/arch/x86/include/asm/scatterlist.h
+++ b/arch/x86/include/asm/scatterlist.h
@@ -1,33 +1,8 @@
1#ifndef _ASM_X86_SCATTERLIST_H 1#ifndef _ASM_X86_SCATTERLIST_H
2#define _ASM_X86_SCATTERLIST_H 2#define _ASM_X86_SCATTERLIST_H
3 3
4#include <asm/types.h>
5
6struct scatterlist {
7#ifdef CONFIG_DEBUG_SG
8 unsigned long sg_magic;
9#endif
10 unsigned long page_link;
11 unsigned int offset;
12 unsigned int length;
13 dma_addr_t dma_address;
14 unsigned int dma_length;
15};
16
17#define ARCH_HAS_SG_CHAIN
18#define ISA_DMA_THRESHOLD (0x00ffffff) 4#define ISA_DMA_THRESHOLD (0x00ffffff)
19 5
20/* 6#include <asm-generic/scatterlist.h>
21 * These macros should be used after a pci_map_sg call has been done
22 * to get bus addresses of each of the SG entries and their lengths.
23 * You should only work with the number of sg entries pci_map_sg
24 * returns.
25 */
26#define sg_dma_address(sg) ((sg)->dma_address)
27#ifdef CONFIG_X86_32
28# define sg_dma_len(sg) ((sg)->length)
29#else
30# define sg_dma_len(sg) ((sg)->dma_length)
31#endif
32 7
33#endif /* _ASM_X86_SCATTERLIST_H */ 8#endif /* _ASM_X86_SCATTERLIST_H */
diff --git a/arch/x86/include/asm/shmbuf.h b/arch/x86/include/asm/shmbuf.h
index b51413b74971..83c05fc2de38 100644
--- a/arch/x86/include/asm/shmbuf.h
+++ b/arch/x86/include/asm/shmbuf.h
@@ -1,51 +1 @@
1#ifndef _ASM_X86_SHMBUF_H #include <asm-generic/shmbuf.h>
2#define _ASM_X86_SHMBUF_H
3
4/*
5 * The shmid64_ds structure for x86 architecture.
6 * Note extra padding because this structure is passed back and forth
7 * between kernel and user space.
8 *
9 * Pad space on 32 bit is left for:
10 * - 64-bit time_t to solve y2038 problem
11 * - 2 miscellaneous 32-bit values
12 *
13 * Pad space on 64 bit is left for:
14 * - 2 miscellaneous 64-bit values
15 */
16
17struct shmid64_ds {
18 struct ipc64_perm shm_perm; /* operation perms */
19 size_t shm_segsz; /* size of segment (bytes) */
20 __kernel_time_t shm_atime; /* last attach time */
21#ifdef __i386__
22 unsigned long __unused1;
23#endif
24 __kernel_time_t shm_dtime; /* last detach time */
25#ifdef __i386__
26 unsigned long __unused2;
27#endif
28 __kernel_time_t shm_ctime; /* last change time */
29#ifdef __i386__
30 unsigned long __unused3;
31#endif
32 __kernel_pid_t shm_cpid; /* pid of creator */
33 __kernel_pid_t shm_lpid; /* pid of last operator */
34 unsigned long shm_nattch; /* no. of current attaches */
35 unsigned long __unused4;
36 unsigned long __unused5;
37};
38
39struct shminfo64 {
40 unsigned long shmmax;
41 unsigned long shmmin;
42 unsigned long shmmni;
43 unsigned long shmseg;
44 unsigned long shmall;
45 unsigned long __unused1;
46 unsigned long __unused2;
47 unsigned long __unused3;
48 unsigned long __unused4;
49};
50
51#endif /* _ASM_X86_SHMBUF_H */
diff --git a/arch/x86/include/asm/socket.h b/arch/x86/include/asm/socket.h
index ca8bf2cd0ba9..6b71384b9d8b 100644
--- a/arch/x86/include/asm/socket.h
+++ b/arch/x86/include/asm/socket.h
@@ -1,60 +1 @@
1#ifndef _ASM_X86_SOCKET_H #include <asm-generic/socket.h>
2#define _ASM_X86_SOCKET_H
3
4#include <asm/sockios.h>
5
6/* For setsockopt(2) */
7#define SOL_SOCKET 1
8
9#define SO_DEBUG 1
10#define SO_REUSEADDR 2
11#define SO_TYPE 3
12#define SO_ERROR 4
13#define SO_DONTROUTE 5
14#define SO_BROADCAST 6
15#define SO_SNDBUF 7
16#define SO_RCVBUF 8
17#define SO_SNDBUFFORCE 32
18#define SO_RCVBUFFORCE 33
19#define SO_KEEPALIVE 9
20#define SO_OOBINLINE 10
21#define SO_NO_CHECK 11
22#define SO_PRIORITY 12
23#define SO_LINGER 13
24#define SO_BSDCOMPAT 14
25/* To add :#define SO_REUSEPORT 15 */
26#define SO_PASSCRED 16
27#define SO_PEERCRED 17
28#define SO_RCVLOWAT 18
29#define SO_SNDLOWAT 19
30#define SO_RCVTIMEO 20
31#define SO_SNDTIMEO 21
32
33/* Security levels - as per NRL IPv6 - don't actually do anything */
34#define SO_SECURITY_AUTHENTICATION 22
35#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
36#define SO_SECURITY_ENCRYPTION_NETWORK 24
37
38#define SO_BINDTODEVICE 25
39
40/* Socket filtering */
41#define SO_ATTACH_FILTER 26
42#define SO_DETACH_FILTER 27
43
44#define SO_PEERNAME 28
45#define SO_TIMESTAMP 29
46#define SCM_TIMESTAMP SO_TIMESTAMP
47
48#define SO_ACCEPTCONN 30
49
50#define SO_PEERSEC 31
51#define SO_PASSSEC 34
52#define SO_TIMESTAMPNS 35
53#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
54
55#define SO_MARK 36
56
57#define SO_TIMESTAMPING 37
58#define SCM_TIMESTAMPING SO_TIMESTAMPING
59
60#endif /* _ASM_X86_SOCKET_H */
diff --git a/arch/x86/include/asm/sockios.h b/arch/x86/include/asm/sockios.h
index 49cc72b5d3c9..def6d4746ee7 100644
--- a/arch/x86/include/asm/sockios.h
+++ b/arch/x86/include/asm/sockios.h
@@ -1,13 +1 @@
1#ifndef _ASM_X86_SOCKIOS_H #include <asm-generic/sockios.h>
2#define _ASM_X86_SOCKIOS_H
3
4/* Socket-level I/O control calls. */
5#define FIOSETOWN 0x8901
6#define SIOCSPGRP 0x8902
7#define FIOGETOWN 0x8903
8#define SIOCGPGRP 0x8904
9#define SIOCATMARK 0x8905
10#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
11#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
12
13#endif /* _ASM_X86_SOCKIOS_H */
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index c2d742c6e15f..157517763565 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -48,7 +48,7 @@
48 * head_32 for boot CPU and setup_per_cpu_areas() for others. 48 * head_32 for boot CPU and setup_per_cpu_areas() for others.
49 */ 49 */
50#define GDT_STACK_CANARY_INIT \ 50#define GDT_STACK_CANARY_INIT \
51 [GDT_ENTRY_STACK_CANARY] = { { { 0x00000018, 0x00409000 } } }, 51 [GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
52 52
53/* 53/*
54 * Initialize the stackprotector canary value. 54 * Initialize the stackprotector canary value.
@@ -78,21 +78,19 @@ static __always_inline void boot_init_stack_canary(void)
78#ifdef CONFIG_X86_64 78#ifdef CONFIG_X86_64
79 percpu_write(irq_stack_union.stack_canary, canary); 79 percpu_write(irq_stack_union.stack_canary, canary);
80#else 80#else
81 percpu_write(stack_canary, canary); 81 percpu_write(stack_canary.canary, canary);
82#endif 82#endif
83} 83}
84 84
85static inline void setup_stack_canary_segment(int cpu) 85static inline void setup_stack_canary_segment(int cpu)
86{ 86{
87#ifdef CONFIG_X86_32 87#ifdef CONFIG_X86_32
88 unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu) - 20; 88 unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
89 struct desc_struct *gdt_table = get_cpu_gdt_table(cpu); 89 struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
90 struct desc_struct desc; 90 struct desc_struct desc;
91 91
92 desc = gdt_table[GDT_ENTRY_STACK_CANARY]; 92 desc = gdt_table[GDT_ENTRY_STACK_CANARY];
93 desc.base0 = canary & 0xffff; 93 set_desc_base(&desc, canary);
94 desc.base1 = (canary >> 16) & 0xff;
95 desc.base2 = (canary >> 24) & 0xff;
96 write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S); 94 write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S);
97#endif 95#endif
98} 96}
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 643c59b4bc6e..f08f97374892 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -31,7 +31,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
31 "movl %P[task_canary](%[next]), %%ebx\n\t" \ 31 "movl %P[task_canary](%[next]), %%ebx\n\t" \
32 "movl %%ebx, "__percpu_arg([stack_canary])"\n\t" 32 "movl %%ebx, "__percpu_arg([stack_canary])"\n\t"
33#define __switch_canary_oparam \ 33#define __switch_canary_oparam \
34 , [stack_canary] "=m" (per_cpu_var(stack_canary)) 34 , [stack_canary] "=m" (per_cpu_var(stack_canary.canary))
35#define __switch_canary_iparam \ 35#define __switch_canary_iparam \
36 , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) 36 , [task_canary] "i" (offsetof(struct task_struct, stack_canary))
37#else /* CC_STACKPROTECTOR */ 37#else /* CC_STACKPROTECTOR */
@@ -150,33 +150,6 @@ do { \
150#endif 150#endif
151 151
152#ifdef __KERNEL__ 152#ifdef __KERNEL__
153#define _set_base(addr, base) do { unsigned long __pr; \
154__asm__ __volatile__ ("movw %%dx,%1\n\t" \
155 "rorl $16,%%edx\n\t" \
156 "movb %%dl,%2\n\t" \
157 "movb %%dh,%3" \
158 :"=&d" (__pr) \
159 :"m" (*((addr)+2)), \
160 "m" (*((addr)+4)), \
161 "m" (*((addr)+7)), \
162 "0" (base) \
163 ); } while (0)
164
165#define _set_limit(addr, limit) do { unsigned long __lr; \
166__asm__ __volatile__ ("movw %%dx,%1\n\t" \
167 "rorl $16,%%edx\n\t" \
168 "movb %2,%%dh\n\t" \
169 "andb $0xf0,%%dh\n\t" \
170 "orb %%dh,%%dl\n\t" \
171 "movb %%dl,%2" \
172 :"=&d" (__lr) \
173 :"m" (*(addr)), \
174 "m" (*((addr)+6)), \
175 "0" (limit) \
176 ); } while (0)
177
178#define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base))
179#define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1))
180 153
181extern void native_load_gs_index(unsigned); 154extern void native_load_gs_index(unsigned);
182 155
diff --git a/arch/x86/include/asm/termbits.h b/arch/x86/include/asm/termbits.h
index af1b70ea440f..3935b106de79 100644
--- a/arch/x86/include/asm/termbits.h
+++ b/arch/x86/include/asm/termbits.h
@@ -1,198 +1 @@
1#ifndef _ASM_X86_TERMBITS_H #include <asm-generic/termbits.h>
2#define _ASM_X86_TERMBITS_H
3
4#include <linux/posix_types.h>
5
6typedef unsigned char cc_t;
7typedef unsigned int speed_t;
8typedef unsigned int tcflag_t;
9
10#define NCCS 19
11struct termios {
12 tcflag_t c_iflag; /* input mode flags */
13 tcflag_t c_oflag; /* output mode flags */
14 tcflag_t c_cflag; /* control mode flags */
15 tcflag_t c_lflag; /* local mode flags */
16 cc_t c_line; /* line discipline */
17 cc_t c_cc[NCCS]; /* control characters */
18};
19
20struct termios2 {
21 tcflag_t c_iflag; /* input mode flags */
22 tcflag_t c_oflag; /* output mode flags */
23 tcflag_t c_cflag; /* control mode flags */
24 tcflag_t c_lflag; /* local mode flags */
25 cc_t c_line; /* line discipline */
26 cc_t c_cc[NCCS]; /* control characters */
27 speed_t c_ispeed; /* input speed */
28 speed_t c_ospeed; /* output speed */
29};
30
31struct ktermios {
32 tcflag_t c_iflag; /* input mode flags */
33 tcflag_t c_oflag; /* output mode flags */
34 tcflag_t c_cflag; /* control mode flags */
35 tcflag_t c_lflag; /* local mode flags */
36 cc_t c_line; /* line discipline */
37 cc_t c_cc[NCCS]; /* control characters */
38 speed_t c_ispeed; /* input speed */
39 speed_t c_ospeed; /* output speed */
40};
41
42/* c_cc characters */
43#define VINTR 0
44#define VQUIT 1
45#define VERASE 2
46#define VKILL 3
47#define VEOF 4
48#define VTIME 5
49#define VMIN 6
50#define VSWTC 7
51#define VSTART 8
52#define VSTOP 9
53#define VSUSP 10
54#define VEOL 11
55#define VREPRINT 12
56#define VDISCARD 13
57#define VWERASE 14
58#define VLNEXT 15
59#define VEOL2 16
60
61/* c_iflag bits */
62#define IGNBRK 0000001
63#define BRKINT 0000002
64#define IGNPAR 0000004
65#define PARMRK 0000010
66#define INPCK 0000020
67#define ISTRIP 0000040
68#define INLCR 0000100
69#define IGNCR 0000200
70#define ICRNL 0000400
71#define IUCLC 0001000
72#define IXON 0002000
73#define IXANY 0004000
74#define IXOFF 0010000
75#define IMAXBEL 0020000
76#define IUTF8 0040000
77
78/* c_oflag bits */
79#define OPOST 0000001
80#define OLCUC 0000002
81#define ONLCR 0000004
82#define OCRNL 0000010
83#define ONOCR 0000020
84#define ONLRET 0000040
85#define OFILL 0000100
86#define OFDEL 0000200
87#define NLDLY 0000400
88#define NL0 0000000
89#define NL1 0000400
90#define CRDLY 0003000
91#define CR0 0000000
92#define CR1 0001000
93#define CR2 0002000
94#define CR3 0003000
95#define TABDLY 0014000
96#define TAB0 0000000
97#define TAB1 0004000
98#define TAB2 0010000
99#define TAB3 0014000
100#define XTABS 0014000
101#define BSDLY 0020000
102#define BS0 0000000
103#define BS1 0020000
104#define VTDLY 0040000
105#define VT0 0000000
106#define VT1 0040000
107#define FFDLY 0100000
108#define FF0 0000000
109#define FF1 0100000
110
111/* c_cflag bit meaning */
112#define CBAUD 0010017
113#define B0 0000000 /* hang up */
114#define B50 0000001
115#define B75 0000002
116#define B110 0000003
117#define B134 0000004
118#define B150 0000005
119#define B200 0000006
120#define B300 0000007
121#define B600 0000010
122#define B1200 0000011
123#define B1800 0000012
124#define B2400 0000013
125#define B4800 0000014
126#define B9600 0000015
127#define B19200 0000016
128#define B38400 0000017
129#define EXTA B19200
130#define EXTB B38400
131#define CSIZE 0000060
132#define CS5 0000000
133#define CS6 0000020
134#define CS7 0000040
135#define CS8 0000060
136#define CSTOPB 0000100
137#define CREAD 0000200
138#define PARENB 0000400
139#define PARODD 0001000
140#define HUPCL 0002000
141#define CLOCAL 0004000
142#define CBAUDEX 0010000
143#define BOTHER 0010000 /* non standard rate */
144#define B57600 0010001
145#define B115200 0010002
146#define B230400 0010003
147#define B460800 0010004
148#define B500000 0010005
149#define B576000 0010006
150#define B921600 0010007
151#define B1000000 0010010
152#define B1152000 0010011
153#define B1500000 0010012
154#define B2000000 0010013
155#define B2500000 0010014
156#define B3000000 0010015
157#define B3500000 0010016
158#define B4000000 0010017
159#define CIBAUD 002003600000 /* input baud rate */
160#define CMSPAR 010000000000 /* mark or space (stick) parity */
161#define CRTSCTS 020000000000 /* flow control */
162
163#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
164
165/* c_lflag bits */
166#define ISIG 0000001
167#define ICANON 0000002
168#define XCASE 0000004
169#define ECHO 0000010
170#define ECHOE 0000020
171#define ECHOK 0000040
172#define ECHONL 0000100
173#define NOFLSH 0000200
174#define TOSTOP 0000400
175#define ECHOCTL 0001000
176#define ECHOPRT 0002000
177#define ECHOKE 0004000
178#define FLUSHO 0010000
179#define PENDIN 0040000
180#define IEXTEN 0100000
181
182/* tcflow() and TCXONC use these */
183#define TCOOFF 0
184#define TCOON 1
185#define TCIOFF 2
186#define TCION 3
187
188/* tcflush() and TCFLSH use these */
189#define TCIFLUSH 0
190#define TCOFLUSH 1
191#define TCIOFLUSH 2
192
193/* tcsetattr uses these */
194#define TCSANOW 0
195#define TCSADRAIN 1
196#define TCSAFLUSH 2
197
198#endif /* _ASM_X86_TERMBITS_H */
diff --git a/arch/x86/include/asm/termios.h b/arch/x86/include/asm/termios.h
index c4ee8056baca..280d78a9d966 100644
--- a/arch/x86/include/asm/termios.h
+++ b/arch/x86/include/asm/termios.h
@@ -1,114 +1 @@
1#ifndef _ASM_X86_TERMIOS_H #include <asm-generic/termios.h>
2#define _ASM_X86_TERMIOS_H
3
4#include <asm/termbits.h>
5#include <asm/ioctls.h>
6
7struct winsize {
8 unsigned short ws_row;
9 unsigned short ws_col;
10 unsigned short ws_xpixel;
11 unsigned short ws_ypixel;
12};
13
14#define NCC 8
15struct termio {
16 unsigned short c_iflag; /* input mode flags */
17 unsigned short c_oflag; /* output mode flags */
18 unsigned short c_cflag; /* control mode flags */
19 unsigned short c_lflag; /* local mode flags */
20 unsigned char c_line; /* line discipline */
21 unsigned char c_cc[NCC]; /* control characters */
22};
23
24/* modem lines */
25#define TIOCM_LE 0x001
26#define TIOCM_DTR 0x002
27#define TIOCM_RTS 0x004
28#define TIOCM_ST 0x008
29#define TIOCM_SR 0x010
30#define TIOCM_CTS 0x020
31#define TIOCM_CAR 0x040
32#define TIOCM_RNG 0x080
33#define TIOCM_DSR 0x100
34#define TIOCM_CD TIOCM_CAR
35#define TIOCM_RI TIOCM_RNG
36#define TIOCM_OUT1 0x2000
37#define TIOCM_OUT2 0x4000
38#define TIOCM_LOOP 0x8000
39
40/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
41
42#ifdef __KERNEL__
43
44#include <asm/uaccess.h>
45
46/* intr=^C quit=^\ erase=del kill=^U
47 eof=^D vtime=\0 vmin=\1 sxtc=\0
48 start=^Q stop=^S susp=^Z eol=\0
49 reprint=^R discard=^U werase=^W lnext=^V
50 eol2=\0
51*/
52#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
53
54/*
55 * Translate a "termio" structure into a "termios". Ugh.
56 */
57#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
58 unsigned short __tmp; \
59 get_user(__tmp,&(termio)->x); \
60 *(unsigned short *) &(termios)->x = __tmp; \
61}
62
63static inline int user_termio_to_kernel_termios(struct ktermios *termios,
64 struct termio __user *termio)
65{
66 SET_LOW_TERMIOS_BITS(termios, termio, c_iflag);
67 SET_LOW_TERMIOS_BITS(termios, termio, c_oflag);
68 SET_LOW_TERMIOS_BITS(termios, termio, c_cflag);
69 SET_LOW_TERMIOS_BITS(termios, termio, c_lflag);
70 get_user(termios->c_line, &termio->c_line);
71 return copy_from_user(termios->c_cc, termio->c_cc, NCC);
72}
73
74/*
75 * Translate a "termios" structure into a "termio". Ugh.
76 */
77static inline int kernel_termios_to_user_termio(struct termio __user *termio,
78 struct ktermios *termios)
79{
80 put_user((termios)->c_iflag, &(termio)->c_iflag);
81 put_user((termios)->c_oflag, &(termio)->c_oflag);
82 put_user((termios)->c_cflag, &(termio)->c_cflag);
83 put_user((termios)->c_lflag, &(termio)->c_lflag);
84 put_user((termios)->c_line, &(termio)->c_line);
85 return copy_to_user((termio)->c_cc, (termios)->c_cc, NCC);
86}
87
88static inline int user_termios_to_kernel_termios(struct ktermios *k,
89 struct termios2 __user *u)
90{
91 return copy_from_user(k, u, sizeof(struct termios2));
92}
93
94static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
95 struct ktermios *k)
96{
97 return copy_to_user(u, k, sizeof(struct termios2));
98}
99
100static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
101 struct termios __user *u)
102{
103 return copy_from_user(k, u, sizeof(struct termios));
104}
105
106static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
107 struct ktermios *k)
108{
109 return copy_to_user(u, k, sizeof(struct termios));
110}
111
112#endif /* __KERNEL__ */
113
114#endif /* _ASM_X86_TERMIOS_H */
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 6f7786aea4fc..d27d0a2fec4c 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -214,7 +214,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack);
214static inline struct thread_info *current_thread_info(void) 214static inline struct thread_info *current_thread_info(void)
215{ 215{
216 struct thread_info *ti; 216 struct thread_info *ti;
217 ti = (void *)(percpu_read(kernel_stack) + 217 ti = (void *)(percpu_read_stable(kernel_stack) +
218 KERNEL_STACK_OFFSET - THREAD_SIZE); 218 KERNEL_STACK_OFFSET - THREAD_SIZE);
219 return ti; 219 return ti;
220} 220}
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 066ef590d7e0..26d06e052a18 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -129,25 +129,34 @@ extern unsigned long node_remap_size[];
129#endif 129#endif
130 130
131/* sched_domains SD_NODE_INIT for NUMA machines */ 131/* sched_domains SD_NODE_INIT for NUMA machines */
132#define SD_NODE_INIT (struct sched_domain) { \ 132#define SD_NODE_INIT (struct sched_domain) { \
133 .min_interval = 8, \ 133 .min_interval = 8, \
134 .max_interval = 32, \ 134 .max_interval = 32, \
135 .busy_factor = 32, \ 135 .busy_factor = 32, \
136 .imbalance_pct = 125, \ 136 .imbalance_pct = 125, \
137 .cache_nice_tries = SD_CACHE_NICE_TRIES, \ 137 .cache_nice_tries = SD_CACHE_NICE_TRIES, \
138 .busy_idx = 3, \ 138 .busy_idx = 3, \
139 .idle_idx = SD_IDLE_IDX, \ 139 .idle_idx = SD_IDLE_IDX, \
140 .newidle_idx = SD_NEWIDLE_IDX, \ 140 .newidle_idx = SD_NEWIDLE_IDX, \
141 .wake_idx = 1, \ 141 .wake_idx = 1, \
142 .forkexec_idx = SD_FORKEXEC_IDX, \ 142 .forkexec_idx = SD_FORKEXEC_IDX, \
143 .flags = SD_LOAD_BALANCE \ 143 \
144 | SD_BALANCE_EXEC \ 144 .flags = 1*SD_LOAD_BALANCE \
145 | SD_BALANCE_FORK \ 145 | 1*SD_BALANCE_NEWIDLE \
146 | SD_WAKE_AFFINE \ 146 | 1*SD_BALANCE_EXEC \
147 | SD_WAKE_BALANCE \ 147 | 1*SD_BALANCE_FORK \
148 | SD_SERIALIZE, \ 148 | 0*SD_WAKE_IDLE \
149 .last_balance = jiffies, \ 149 | 1*SD_WAKE_AFFINE \
150 .balance_interval = 1, \ 150 | 1*SD_WAKE_BALANCE \
151 | 0*SD_SHARE_CPUPOWER \
152 | 0*SD_POWERSAVINGS_BALANCE \
153 | 0*SD_SHARE_PKG_RESOURCES \
154 | 1*SD_SERIALIZE \
155 | 1*SD_WAKE_IDLE_FAR \
156 | 0*SD_PREFER_SIBLING \
157 , \
158 .last_balance = jiffies, \
159 .balance_interval = 1, \
151} 160}
152 161
153#ifdef CONFIG_X86_64_ACPI_NUMA 162#ifdef CONFIG_X86_64_ACPI_NUMA
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index bfd74c032fca..4da91ad69e0d 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -81,9 +81,7 @@ extern int panic_on_unrecovered_nmi;
81 81
82void math_error(void __user *); 82void math_error(void __user *);
83void math_emulate(struct math_emu_info *); 83void math_emulate(struct math_emu_info *);
84#ifdef CONFIG_X86_32 84#ifndef CONFIG_X86_32
85unsigned long patch_espfix_desc(unsigned long, unsigned long);
86#else
87asmlinkage void smp_thermal_interrupt(void); 85asmlinkage void smp_thermal_interrupt(void);
88asmlinkage void mce_threshold_interrupt(void); 86asmlinkage void mce_threshold_interrupt(void);
89#endif 87#endif
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index 09b97745772f..df1da20f4534 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -1,19 +1,11 @@
1#ifndef _ASM_X86_TYPES_H 1#ifndef _ASM_X86_TYPES_H
2#define _ASM_X86_TYPES_H 2#define _ASM_X86_TYPES_H
3 3
4#include <asm-generic/int-ll64.h> 4#define dma_addr_t dma_addr_t
5 5
6#ifndef __ASSEMBLY__ 6#include <asm-generic/types.h>
7
8typedef unsigned short umode_t;
9 7
10#endif /* __ASSEMBLY__ */
11
12/*
13 * These aren't exported outside the kernel to avoid name space clashes
14 */
15#ifdef __KERNEL__ 8#ifdef __KERNEL__
16
17#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
18 10
19typedef u64 dma64_addr_t; 11typedef u64 dma64_addr_t;
diff --git a/arch/x86/include/asm/ucontext.h b/arch/x86/include/asm/ucontext.h
index 87324cf439d9..b7c29c8017f2 100644
--- a/arch/x86/include/asm/ucontext.h
+++ b/arch/x86/include/asm/ucontext.h
@@ -7,12 +7,6 @@
7 * sigcontext struct (uc_mcontext). 7 * sigcontext struct (uc_mcontext).
8 */ 8 */
9 9
10struct ucontext { 10#include <asm-generic/ucontext.h>
11 unsigned long uc_flags;
12 struct ucontext *uc_link;
13 stack_t uc_stack;
14 struct sigcontext uc_mcontext;
15 sigset_t uc_sigmask; /* mask last for extensibility */
16};
17 11
18#endif /* _ASM_X86_UCONTEXT_H */ 12#endif /* _ASM_X86_UCONTEXT_H */
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 11be5ad2e0e9..272514c2d456 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -55,6 +55,7 @@
55#define SECONDARY_EXEC_ENABLE_EPT 0x00000002 55#define SECONDARY_EXEC_ENABLE_EPT 0x00000002
56#define SECONDARY_EXEC_ENABLE_VPID 0x00000020 56#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
57#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 57#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
58#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
58 59
59 60
60#define PIN_BASED_EXT_INTR_MASK 0x00000001 61#define PIN_BASED_EXT_INTR_MASK 0x00000001
@@ -351,9 +352,16 @@ enum vmcs_field {
351#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 352#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0
352#define VMX_EPT_EXTENT_CONTEXT 1 353#define VMX_EPT_EXTENT_CONTEXT 1
353#define VMX_EPT_EXTENT_GLOBAL 2 354#define VMX_EPT_EXTENT_GLOBAL 2
355
356#define VMX_EPT_EXECUTE_ONLY_BIT (1ull)
357#define VMX_EPT_PAGE_WALK_4_BIT (1ull << 6)
358#define VMX_EPTP_UC_BIT (1ull << 8)
359#define VMX_EPTP_WB_BIT (1ull << 14)
360#define VMX_EPT_2MB_PAGE_BIT (1ull << 16)
354#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) 361#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24)
355#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) 362#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25)
356#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) 363#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26)
364
357#define VMX_EPT_DEFAULT_GAW 3 365#define VMX_EPT_DEFAULT_GAW 3
358#define VMX_EPT_MAX_GAW 0x4 366#define VMX_EPT_MAX_GAW 0x4
359#define VMX_EPT_MT_EPTE_SHIFT 3 367#define VMX_EPT_MT_EPTE_SHIFT 3
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 6b8ca3a0285d..67e929b89875 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -833,106 +833,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
833extern int es7000_plat; 833extern int es7000_plat;
834#endif 834#endif
835 835
836static struct {
837 int gsi_base;
838 int gsi_end;
839} mp_ioapic_routing[MAX_IO_APICS];
840
841int mp_find_ioapic(int gsi)
842{
843 int i = 0;
844
845 /* Find the IOAPIC that manages this GSI. */
846 for (i = 0; i < nr_ioapics; i++) {
847 if ((gsi >= mp_ioapic_routing[i].gsi_base)
848 && (gsi <= mp_ioapic_routing[i].gsi_end))
849 return i;
850 }
851
852 printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
853 return -1;
854}
855
856int mp_find_ioapic_pin(int ioapic, int gsi)
857{
858 if (WARN_ON(ioapic == -1))
859 return -1;
860 if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end))
861 return -1;
862
863 return gsi - mp_ioapic_routing[ioapic].gsi_base;
864}
865
866static u8 __init uniq_ioapic_id(u8 id)
867{
868#ifdef CONFIG_X86_32
869 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
870 !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
871 return io_apic_get_unique_id(nr_ioapics, id);
872 else
873 return id;
874#else
875 int i;
876 DECLARE_BITMAP(used, 256);
877 bitmap_zero(used, 256);
878 for (i = 0; i < nr_ioapics; i++) {
879 struct mpc_ioapic *ia = &mp_ioapics[i];
880 __set_bit(ia->apicid, used);
881 }
882 if (!test_bit(id, used))
883 return id;
884 return find_first_zero_bit(used, 256);
885#endif
886}
887
888static int bad_ioapic(unsigned long address)
889{
890 if (nr_ioapics >= MAX_IO_APICS) {
891 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
892 "(found %d)\n", MAX_IO_APICS, nr_ioapics);
893 panic("Recompile kernel with bigger MAX_IO_APICS!\n");
894 }
895 if (!address) {
896 printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
897 " found in table, skipping!\n");
898 return 1;
899 }
900 return 0;
901}
902
903void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
904{
905 int idx = 0;
906
907 if (bad_ioapic(address))
908 return;
909
910 idx = nr_ioapics;
911
912 mp_ioapics[idx].type = MP_IOAPIC;
913 mp_ioapics[idx].flags = MPC_APIC_USABLE;
914 mp_ioapics[idx].apicaddr = address;
915
916 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
917 mp_ioapics[idx].apicid = uniq_ioapic_id(id);
918 mp_ioapics[idx].apicver = io_apic_get_version(idx);
919
920 /*
921 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
922 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
923 */
924 mp_ioapic_routing[idx].gsi_base = gsi_base;
925 mp_ioapic_routing[idx].gsi_end = gsi_base +
926 io_apic_get_redir_entries(idx);
927
928 printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
929 "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
930 mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
931 mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
932
933 nr_ioapics++;
934}
935
936int __init acpi_probe_gsi(void) 836int __init acpi_probe_gsi(void)
937{ 837{
938 int idx; 838 int idx;
@@ -947,7 +847,7 @@ int __init acpi_probe_gsi(void)
947 847
948 max_gsi = 0; 848 max_gsi = 0;
949 for (idx = 0; idx < nr_ioapics; idx++) { 849 for (idx = 0; idx < nr_ioapics; idx++) {
950 gsi = mp_ioapic_routing[idx].gsi_end; 850 gsi = mp_gsi_routing[idx].gsi_end;
951 851
952 if (gsi > max_gsi) 852 if (gsi > max_gsi)
953 max_gsi = gsi; 853 max_gsi = gsi;
@@ -1179,9 +1079,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
1179 * If MPS is present, it will handle them, 1079 * If MPS is present, it will handle them,
1180 * otherwise the system will stay in PIC mode 1080 * otherwise the system will stay in PIC mode
1181 */ 1081 */
1182 if (acpi_disabled || acpi_noirq) { 1082 if (acpi_disabled || acpi_noirq)
1183 return -ENODEV; 1083 return -ENODEV;
1184 }
1185 1084
1186 if (!cpu_has_apic) 1085 if (!cpu_has_apic)
1187 return -ENODEV; 1086 return -ENODEV;
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index f57658702571..de7353c0ce9c 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2,6 +2,7 @@
2#include <linux/sched.h> 2#include <linux/sched.h>
3#include <linux/mutex.h> 3#include <linux/mutex.h>
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/stringify.h>
5#include <linux/kprobes.h> 6#include <linux/kprobes.h>
6#include <linux/mm.h> 7#include <linux/mm.h>
7#include <linux/vmalloc.h> 8#include <linux/vmalloc.h>
@@ -32,7 +33,7 @@ __setup("smp-alt-boot", bootonly);
32#define smp_alt_once 1 33#define smp_alt_once 1
33#endif 34#endif
34 35
35static int debug_alternative; 36static int __initdata_or_module debug_alternative;
36 37
37static int __init debug_alt(char *str) 38static int __init debug_alt(char *str)
38{ 39{
@@ -51,7 +52,7 @@ static int __init setup_noreplace_smp(char *str)
51__setup("noreplace-smp", setup_noreplace_smp); 52__setup("noreplace-smp", setup_noreplace_smp);
52 53
53#ifdef CONFIG_PARAVIRT 54#ifdef CONFIG_PARAVIRT
54static int noreplace_paravirt = 0; 55static int __initdata_or_module noreplace_paravirt = 0;
55 56
56static int __init setup_noreplace_paravirt(char *str) 57static int __init setup_noreplace_paravirt(char *str)
57{ 58{
@@ -64,16 +65,17 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
64#define DPRINTK(fmt, args...) if (debug_alternative) \ 65#define DPRINTK(fmt, args...) if (debug_alternative) \
65 printk(KERN_DEBUG fmt, args) 66 printk(KERN_DEBUG fmt, args)
66 67
67#ifdef GENERIC_NOP1 68#if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64)
68/* Use inline assembly to define this because the nops are defined 69/* Use inline assembly to define this because the nops are defined
69 as inline assembly strings in the include files and we cannot 70 as inline assembly strings in the include files and we cannot
70 get them easily into strings. */ 71 get them easily into strings. */
71asm("\t.section .rodata, \"a\"\nintelnops: " 72asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: "
72 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 73 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
73 GENERIC_NOP7 GENERIC_NOP8 74 GENERIC_NOP7 GENERIC_NOP8
74 "\t.previous"); 75 "\t.previous");
75extern const unsigned char intelnops[]; 76extern const unsigned char intelnops[];
76static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = { 77static const unsigned char *const __initconst_or_module
78intel_nops[ASM_NOP_MAX+1] = {
77 NULL, 79 NULL,
78 intelnops, 80 intelnops,
79 intelnops + 1, 81 intelnops + 1,
@@ -87,12 +89,13 @@ static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
87#endif 89#endif
88 90
89#ifdef K8_NOP1 91#ifdef K8_NOP1
90asm("\t.section .rodata, \"a\"\nk8nops: " 92asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: "
91 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 93 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
92 K8_NOP7 K8_NOP8 94 K8_NOP7 K8_NOP8
93 "\t.previous"); 95 "\t.previous");
94extern const unsigned char k8nops[]; 96extern const unsigned char k8nops[];
95static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = { 97static const unsigned char *const __initconst_or_module
98k8_nops[ASM_NOP_MAX+1] = {
96 NULL, 99 NULL,
97 k8nops, 100 k8nops,
98 k8nops + 1, 101 k8nops + 1,
@@ -105,13 +108,14 @@ static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
105}; 108};
106#endif 109#endif
107 110
108#ifdef K7_NOP1 111#if defined(K7_NOP1) && !defined(CONFIG_X86_64)
109asm("\t.section .rodata, \"a\"\nk7nops: " 112asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: "
110 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 113 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
111 K7_NOP7 K7_NOP8 114 K7_NOP7 K7_NOP8
112 "\t.previous"); 115 "\t.previous");
113extern const unsigned char k7nops[]; 116extern const unsigned char k7nops[];
114static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = { 117static const unsigned char *const __initconst_or_module
118k7_nops[ASM_NOP_MAX+1] = {
115 NULL, 119 NULL,
116 k7nops, 120 k7nops,
117 k7nops + 1, 121 k7nops + 1,
@@ -125,12 +129,13 @@ static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
125#endif 129#endif
126 130
127#ifdef P6_NOP1 131#ifdef P6_NOP1
128asm("\t.section .rodata, \"a\"\np6nops: " 132asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: "
129 P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 133 P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
130 P6_NOP7 P6_NOP8 134 P6_NOP7 P6_NOP8
131 "\t.previous"); 135 "\t.previous");
132extern const unsigned char p6nops[]; 136extern const unsigned char p6nops[];
133static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { 137static const unsigned char *const __initconst_or_module
138p6_nops[ASM_NOP_MAX+1] = {
134 NULL, 139 NULL,
135 p6nops, 140 p6nops,
136 p6nops + 1, 141 p6nops + 1,
@@ -146,7 +151,7 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
146#ifdef CONFIG_X86_64 151#ifdef CONFIG_X86_64
147 152
148extern char __vsyscall_0; 153extern char __vsyscall_0;
149const unsigned char *const *find_nop_table(void) 154static const unsigned char *const *__init_or_module find_nop_table(void)
150{ 155{
151 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && 156 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
152 boot_cpu_has(X86_FEATURE_NOPL)) 157 boot_cpu_has(X86_FEATURE_NOPL))
@@ -157,7 +162,7 @@ const unsigned char *const *find_nop_table(void)
157 162
158#else /* CONFIG_X86_64 */ 163#else /* CONFIG_X86_64 */
159 164
160const unsigned char *const *find_nop_table(void) 165static const unsigned char *const *__init_or_module find_nop_table(void)
161{ 166{
162 if (boot_cpu_has(X86_FEATURE_K8)) 167 if (boot_cpu_has(X86_FEATURE_K8))
163 return k8_nops; 168 return k8_nops;
@@ -172,7 +177,7 @@ const unsigned char *const *find_nop_table(void)
172#endif /* CONFIG_X86_64 */ 177#endif /* CONFIG_X86_64 */
173 178
174/* Use this to add nops to a buffer, then text_poke the whole buffer. */ 179/* Use this to add nops to a buffer, then text_poke the whole buffer. */
175void add_nops(void *insns, unsigned int len) 180static void __init_or_module add_nops(void *insns, unsigned int len)
176{ 181{
177 const unsigned char *const *noptable = find_nop_table(); 182 const unsigned char *const *noptable = find_nop_table();
178 183
@@ -185,10 +190,10 @@ void add_nops(void *insns, unsigned int len)
185 len -= noplen; 190 len -= noplen;
186 } 191 }
187} 192}
188EXPORT_SYMBOL_GPL(add_nops);
189 193
190extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; 194extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
191extern u8 *__smp_locks[], *__smp_locks_end[]; 195extern u8 *__smp_locks[], *__smp_locks_end[];
196static void *text_poke_early(void *addr, const void *opcode, size_t len);
192 197
193/* Replace instructions with better alternatives for this CPU type. 198/* Replace instructions with better alternatives for this CPU type.
194 This runs before SMP is initialized to avoid SMP problems with 199 This runs before SMP is initialized to avoid SMP problems with
@@ -196,7 +201,8 @@ extern u8 *__smp_locks[], *__smp_locks_end[];
196 APs have less capabilities than the boot processor are not handled. 201 APs have less capabilities than the boot processor are not handled.
197 Tough. Make sure you disable such features by hand. */ 202 Tough. Make sure you disable such features by hand. */
198 203
199void apply_alternatives(struct alt_instr *start, struct alt_instr *end) 204void __init_or_module apply_alternatives(struct alt_instr *start,
205 struct alt_instr *end)
200{ 206{
201 struct alt_instr *a; 207 struct alt_instr *a;
202 char insnbuf[MAX_PATCH_LEN]; 208 char insnbuf[MAX_PATCH_LEN];
@@ -279,9 +285,10 @@ static LIST_HEAD(smp_alt_modules);
279static DEFINE_MUTEX(smp_alt); 285static DEFINE_MUTEX(smp_alt);
280static int smp_mode = 1; /* protected by smp_alt */ 286static int smp_mode = 1; /* protected by smp_alt */
281 287
282void alternatives_smp_module_add(struct module *mod, char *name, 288void __init_or_module alternatives_smp_module_add(struct module *mod,
283 void *locks, void *locks_end, 289 char *name,
284 void *text, void *text_end) 290 void *locks, void *locks_end,
291 void *text, void *text_end)
285{ 292{
286 struct smp_alt_module *smp; 293 struct smp_alt_module *smp;
287 294
@@ -317,7 +324,7 @@ void alternatives_smp_module_add(struct module *mod, char *name,
317 mutex_unlock(&smp_alt); 324 mutex_unlock(&smp_alt);
318} 325}
319 326
320void alternatives_smp_module_del(struct module *mod) 327void __init_or_module alternatives_smp_module_del(struct module *mod)
321{ 328{
322 struct smp_alt_module *item; 329 struct smp_alt_module *item;
323 330
@@ -386,8 +393,8 @@ void alternatives_smp_switch(int smp)
386#endif 393#endif
387 394
388#ifdef CONFIG_PARAVIRT 395#ifdef CONFIG_PARAVIRT
389void apply_paravirt(struct paravirt_patch_site *start, 396void __init_or_module apply_paravirt(struct paravirt_patch_site *start,
390 struct paravirt_patch_site *end) 397 struct paravirt_patch_site *end)
391{ 398{
392 struct paravirt_patch_site *p; 399 struct paravirt_patch_site *p;
393 char insnbuf[MAX_PATCH_LEN]; 400 char insnbuf[MAX_PATCH_LEN];
@@ -485,13 +492,14 @@ void __init alternative_instructions(void)
485 * instructions. And on the local CPU you need to be protected again NMI or MCE 492 * instructions. And on the local CPU you need to be protected again NMI or MCE
486 * handlers seeing an inconsistent instruction while you patch. 493 * handlers seeing an inconsistent instruction while you patch.
487 */ 494 */
488void *text_poke_early(void *addr, const void *opcode, size_t len) 495static void *__init_or_module text_poke_early(void *addr, const void *opcode,
496 size_t len)
489{ 497{
490 unsigned long flags; 498 unsigned long flags;
491 local_irq_save(flags); 499 local_irq_save(flags);
492 memcpy(addr, opcode, len); 500 memcpy(addr, opcode, len);
493 local_irq_restore(flags);
494 sync_core(); 501 sync_core();
502 local_irq_restore(flags);
495 /* Could also do a CLFLUSH here to speed up CPU recovery; but 503 /* Could also do a CLFLUSH here to speed up CPU recovery; but
496 that causes hangs on some VIA CPUs. */ 504 that causes hangs on some VIA CPUs. */
497 return addr; 505 return addr;
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 6c99f5037801..98f230f6a28d 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -41,9 +41,13 @@ static DEFINE_RWLOCK(amd_iommu_devtable_lock);
41static LIST_HEAD(iommu_pd_list); 41static LIST_HEAD(iommu_pd_list);
42static DEFINE_SPINLOCK(iommu_pd_list_lock); 42static DEFINE_SPINLOCK(iommu_pd_list_lock);
43 43
44#ifdef CONFIG_IOMMU_API 44/*
45 * Domain for untranslated devices - only allocated
46 * if iommu=pt passed on kernel cmd line.
47 */
48static struct protection_domain *pt_domain;
49
45static struct iommu_ops amd_iommu_ops; 50static struct iommu_ops amd_iommu_ops;
46#endif
47 51
48/* 52/*
49 * general struct to manage commands send to an IOMMU 53 * general struct to manage commands send to an IOMMU
@@ -55,16 +59,16 @@ struct iommu_cmd {
55static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, 59static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
56 struct unity_map_entry *e); 60 struct unity_map_entry *e);
57static struct dma_ops_domain *find_protection_domain(u16 devid); 61static struct dma_ops_domain *find_protection_domain(u16 devid);
58static u64* alloc_pte(struct protection_domain *dom, 62static u64 *alloc_pte(struct protection_domain *domain,
59 unsigned long address, u64 63 unsigned long address, int end_lvl,
60 **pte_page, gfp_t gfp); 64 u64 **pte_page, gfp_t gfp);
61static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, 65static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
62 unsigned long start_page, 66 unsigned long start_page,
63 unsigned int pages); 67 unsigned int pages);
64 68static void reset_iommu_command_buffer(struct amd_iommu *iommu);
65#ifndef BUS_NOTIFY_UNBOUND_DRIVER 69static u64 *fetch_pte(struct protection_domain *domain,
66#define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 70 unsigned long address, int map_size);
67#endif 71static void update_domain(struct protection_domain *domain);
68 72
69#ifdef CONFIG_AMD_IOMMU_STATS 73#ifdef CONFIG_AMD_IOMMU_STATS
70 74
@@ -138,7 +142,25 @@ static int iommu_has_npcache(struct amd_iommu *iommu)
138 * 142 *
139 ****************************************************************************/ 143 ****************************************************************************/
140 144
141static void iommu_print_event(void *__evt) 145static void dump_dte_entry(u16 devid)
146{
147 int i;
148
149 for (i = 0; i < 8; ++i)
150 pr_err("AMD-Vi: DTE[%d]: %08x\n", i,
151 amd_iommu_dev_table[devid].data[i]);
152}
153
154static void dump_command(unsigned long phys_addr)
155{
156 struct iommu_cmd *cmd = phys_to_virt(phys_addr);
157 int i;
158
159 for (i = 0; i < 4; ++i)
160 pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
161}
162
163static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
142{ 164{
143 u32 *event = __evt; 165 u32 *event = __evt;
144 int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; 166 int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
@@ -147,7 +169,7 @@ static void iommu_print_event(void *__evt)
147 int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; 169 int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
148 u64 address = (u64)(((u64)event[3]) << 32) | event[2]; 170 u64 address = (u64)(((u64)event[3]) << 32) | event[2];
149 171
150 printk(KERN_ERR "AMD IOMMU: Event logged ["); 172 printk(KERN_ERR "AMD-Vi: Event logged [");
151 173
152 switch (type) { 174 switch (type) {
153 case EVENT_TYPE_ILL_DEV: 175 case EVENT_TYPE_ILL_DEV:
@@ -155,6 +177,7 @@ static void iommu_print_event(void *__evt)
155 "address=0x%016llx flags=0x%04x]\n", 177 "address=0x%016llx flags=0x%04x]\n",
156 PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), 178 PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
157 address, flags); 179 address, flags);
180 dump_dte_entry(devid);
158 break; 181 break;
159 case EVENT_TYPE_IO_FAULT: 182 case EVENT_TYPE_IO_FAULT:
160 printk("IO_PAGE_FAULT device=%02x:%02x.%x " 183 printk("IO_PAGE_FAULT device=%02x:%02x.%x "
@@ -176,6 +199,8 @@ static void iommu_print_event(void *__evt)
176 break; 199 break;
177 case EVENT_TYPE_ILL_CMD: 200 case EVENT_TYPE_ILL_CMD:
178 printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); 201 printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
202 reset_iommu_command_buffer(iommu);
203 dump_command(address);
179 break; 204 break;
180 case EVENT_TYPE_CMD_HARD_ERR: 205 case EVENT_TYPE_CMD_HARD_ERR:
181 printk("COMMAND_HARDWARE_ERROR address=0x%016llx " 206 printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
@@ -209,7 +234,7 @@ static void iommu_poll_events(struct amd_iommu *iommu)
209 tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); 234 tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);
210 235
211 while (head != tail) { 236 while (head != tail) {
212 iommu_print_event(iommu->evt_buf + head); 237 iommu_print_event(iommu, iommu->evt_buf + head);
213 head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; 238 head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;
214 } 239 }
215 240
@@ -296,8 +321,11 @@ static void __iommu_wait_for_completion(struct amd_iommu *iommu)
296 status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; 321 status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
297 writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); 322 writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
298 323
299 if (unlikely(i == EXIT_LOOP_COUNT)) 324 if (unlikely(i == EXIT_LOOP_COUNT)) {
300 panic("AMD IOMMU: Completion wait loop failed\n"); 325 spin_unlock(&iommu->lock);
326 reset_iommu_command_buffer(iommu);
327 spin_lock(&iommu->lock);
328 }
301} 329}
302 330
303/* 331/*
@@ -445,47 +473,78 @@ static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid)
445} 473}
446 474
447/* 475/*
476 * This function flushes one domain on one IOMMU
477 */
478static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid)
479{
480 struct iommu_cmd cmd;
481 unsigned long flags;
482
483 __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
484 domid, 1, 1);
485
486 spin_lock_irqsave(&iommu->lock, flags);
487 __iommu_queue_command(iommu, &cmd);
488 __iommu_completion_wait(iommu);
489 __iommu_wait_for_completion(iommu);
490 spin_unlock_irqrestore(&iommu->lock, flags);
491}
492
493static void flush_all_domains_on_iommu(struct amd_iommu *iommu)
494{
495 int i;
496
497 for (i = 1; i < MAX_DOMAIN_ID; ++i) {
498 if (!test_bit(i, amd_iommu_pd_alloc_bitmap))
499 continue;
500 flush_domain_on_iommu(iommu, i);
501 }
502
503}
504
505/*
448 * This function is used to flush the IO/TLB for a given protection domain 506 * This function is used to flush the IO/TLB for a given protection domain
449 * on every IOMMU in the system 507 * on every IOMMU in the system
450 */ 508 */
451static void iommu_flush_domain(u16 domid) 509static void iommu_flush_domain(u16 domid)
452{ 510{
453 unsigned long flags;
454 struct amd_iommu *iommu; 511 struct amd_iommu *iommu;
455 struct iommu_cmd cmd;
456 512
457 INC_STATS_COUNTER(domain_flush_all); 513 INC_STATS_COUNTER(domain_flush_all);
458 514
459 __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 515 for_each_iommu(iommu)
460 domid, 1, 1); 516 flush_domain_on_iommu(iommu, domid);
461
462 for_each_iommu(iommu) {
463 spin_lock_irqsave(&iommu->lock, flags);
464 __iommu_queue_command(iommu, &cmd);
465 __iommu_completion_wait(iommu);
466 __iommu_wait_for_completion(iommu);
467 spin_unlock_irqrestore(&iommu->lock, flags);
468 }
469} 517}
470 518
471void amd_iommu_flush_all_domains(void) 519void amd_iommu_flush_all_domains(void)
472{ 520{
521 struct amd_iommu *iommu;
522
523 for_each_iommu(iommu)
524 flush_all_domains_on_iommu(iommu);
525}
526
527static void flush_all_devices_for_iommu(struct amd_iommu *iommu)
528{
473 int i; 529 int i;
474 530
475 for (i = 1; i < MAX_DOMAIN_ID; ++i) { 531 for (i = 0; i <= amd_iommu_last_bdf; ++i) {
476 if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) 532 if (iommu != amd_iommu_rlookup_table[i])
477 continue; 533 continue;
478 iommu_flush_domain(i); 534
535 iommu_queue_inv_dev_entry(iommu, i);
536 iommu_completion_wait(iommu);
479 } 537 }
480} 538}
481 539
482void amd_iommu_flush_all_devices(void) 540static void flush_devices_by_domain(struct protection_domain *domain)
483{ 541{
484 struct amd_iommu *iommu; 542 struct amd_iommu *iommu;
485 int i; 543 int i;
486 544
487 for (i = 0; i <= amd_iommu_last_bdf; ++i) { 545 for (i = 0; i <= amd_iommu_last_bdf; ++i) {
488 if (amd_iommu_pd_table[i] == NULL) 546 if ((domain == NULL && amd_iommu_pd_table[i] == NULL) ||
547 (amd_iommu_pd_table[i] != domain))
489 continue; 548 continue;
490 549
491 iommu = amd_iommu_rlookup_table[i]; 550 iommu = amd_iommu_rlookup_table[i];
@@ -497,6 +556,27 @@ void amd_iommu_flush_all_devices(void)
497 } 556 }
498} 557}
499 558
559static void reset_iommu_command_buffer(struct amd_iommu *iommu)
560{
561 pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
562
563 if (iommu->reset_in_progress)
564 panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
565
566 iommu->reset_in_progress = true;
567
568 amd_iommu_reset_cmd_buffer(iommu);
569 flush_all_devices_for_iommu(iommu);
570 flush_all_domains_on_iommu(iommu);
571
572 iommu->reset_in_progress = false;
573}
574
575void amd_iommu_flush_all_devices(void)
576{
577 flush_devices_by_domain(NULL);
578}
579
500/**************************************************************************** 580/****************************************************************************
501 * 581 *
502 * The functions below are used the create the page table mappings for 582 * The functions below are used the create the page table mappings for
@@ -514,18 +594,21 @@ void amd_iommu_flush_all_devices(void)
514static int iommu_map_page(struct protection_domain *dom, 594static int iommu_map_page(struct protection_domain *dom,
515 unsigned long bus_addr, 595 unsigned long bus_addr,
516 unsigned long phys_addr, 596 unsigned long phys_addr,
517 int prot) 597 int prot,
598 int map_size)
518{ 599{
519 u64 __pte, *pte; 600 u64 __pte, *pte;
520 601
521 bus_addr = PAGE_ALIGN(bus_addr); 602 bus_addr = PAGE_ALIGN(bus_addr);
522 phys_addr = PAGE_ALIGN(phys_addr); 603 phys_addr = PAGE_ALIGN(phys_addr);
523 604
524 /* only support 512GB address spaces for now */ 605 BUG_ON(!PM_ALIGNED(map_size, bus_addr));
525 if (bus_addr > IOMMU_MAP_SIZE_L3 || !(prot & IOMMU_PROT_MASK)) 606 BUG_ON(!PM_ALIGNED(map_size, phys_addr));
607
608 if (!(prot & IOMMU_PROT_MASK))
526 return -EINVAL; 609 return -EINVAL;
527 610
528 pte = alloc_pte(dom, bus_addr, NULL, GFP_KERNEL); 611 pte = alloc_pte(dom, bus_addr, map_size, NULL, GFP_KERNEL);
529 612
530 if (IOMMU_PTE_PRESENT(*pte)) 613 if (IOMMU_PTE_PRESENT(*pte))
531 return -EBUSY; 614 return -EBUSY;
@@ -538,29 +621,18 @@ static int iommu_map_page(struct protection_domain *dom,
538 621
539 *pte = __pte; 622 *pte = __pte;
540 623
624 update_domain(dom);
625
541 return 0; 626 return 0;
542} 627}
543 628
544static void iommu_unmap_page(struct protection_domain *dom, 629static void iommu_unmap_page(struct protection_domain *dom,
545 unsigned long bus_addr) 630 unsigned long bus_addr, int map_size)
546{ 631{
547 u64 *pte; 632 u64 *pte = fetch_pte(dom, bus_addr, map_size);
548
549 pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)];
550
551 if (!IOMMU_PTE_PRESENT(*pte))
552 return;
553
554 pte = IOMMU_PTE_PAGE(*pte);
555 pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)];
556 633
557 if (!IOMMU_PTE_PRESENT(*pte)) 634 if (pte)
558 return; 635 *pte = 0;
559
560 pte = IOMMU_PTE_PAGE(*pte);
561 pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)];
562
563 *pte = 0;
564} 636}
565 637
566/* 638/*
@@ -615,7 +687,8 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
615 687
616 for (addr = e->address_start; addr < e->address_end; 688 for (addr = e->address_start; addr < e->address_end;
617 addr += PAGE_SIZE) { 689 addr += PAGE_SIZE) {
618 ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot); 690 ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot,
691 PM_MAP_4k);
619 if (ret) 692 if (ret)
620 return ret; 693 return ret;
621 /* 694 /*
@@ -670,24 +743,29 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
670 * This function checks if there is a PTE for a given dma address. If 743 * This function checks if there is a PTE for a given dma address. If
671 * there is one, it returns the pointer to it. 744 * there is one, it returns the pointer to it.
672 */ 745 */
673static u64* fetch_pte(struct protection_domain *domain, 746static u64 *fetch_pte(struct protection_domain *domain,
674 unsigned long address) 747 unsigned long address, int map_size)
675{ 748{
749 int level;
676 u64 *pte; 750 u64 *pte;
677 751
678 pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(address)]; 752 level = domain->mode - 1;
753 pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
679 754
680 if (!IOMMU_PTE_PRESENT(*pte)) 755 while (level > map_size) {
681 return NULL; 756 if (!IOMMU_PTE_PRESENT(*pte))
757 return NULL;
682 758
683 pte = IOMMU_PTE_PAGE(*pte); 759 level -= 1;
684 pte = &pte[IOMMU_PTE_L1_INDEX(address)];
685 760
686 if (!IOMMU_PTE_PRESENT(*pte)) 761 pte = IOMMU_PTE_PAGE(*pte);
687 return NULL; 762 pte = &pte[PM_LEVEL_INDEX(level, address)];
688 763
689 pte = IOMMU_PTE_PAGE(*pte); 764 if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
690 pte = &pte[IOMMU_PTE_L0_INDEX(address)]; 765 pte = NULL;
766 break;
767 }
768 }
691 769
692 return pte; 770 return pte;
693} 771}
@@ -727,7 +805,7 @@ static int alloc_new_range(struct amd_iommu *iommu,
727 u64 *pte, *pte_page; 805 u64 *pte, *pte_page;
728 806
729 for (i = 0; i < num_ptes; ++i) { 807 for (i = 0; i < num_ptes; ++i) {
730 pte = alloc_pte(&dma_dom->domain, address, 808 pte = alloc_pte(&dma_dom->domain, address, PM_MAP_4k,
731 &pte_page, gfp); 809 &pte_page, gfp);
732 if (!pte) 810 if (!pte)
733 goto out_free; 811 goto out_free;
@@ -760,16 +838,20 @@ static int alloc_new_range(struct amd_iommu *iommu,
760 for (i = dma_dom->aperture[index]->offset; 838 for (i = dma_dom->aperture[index]->offset;
761 i < dma_dom->aperture_size; 839 i < dma_dom->aperture_size;
762 i += PAGE_SIZE) { 840 i += PAGE_SIZE) {
763 u64 *pte = fetch_pte(&dma_dom->domain, i); 841 u64 *pte = fetch_pte(&dma_dom->domain, i, PM_MAP_4k);
764 if (!pte || !IOMMU_PTE_PRESENT(*pte)) 842 if (!pte || !IOMMU_PTE_PRESENT(*pte))
765 continue; 843 continue;
766 844
767 dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1); 845 dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1);
768 } 846 }
769 847
848 update_domain(&dma_dom->domain);
849
770 return 0; 850 return 0;
771 851
772out_free: 852out_free:
853 update_domain(&dma_dom->domain);
854
773 free_page((unsigned long)dma_dom->aperture[index]->bitmap); 855 free_page((unsigned long)dma_dom->aperture[index]->bitmap);
774 856
775 kfree(dma_dom->aperture[index]); 857 kfree(dma_dom->aperture[index]);
@@ -1009,7 +1091,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
1009 dma_dom->domain.id = domain_id_alloc(); 1091 dma_dom->domain.id = domain_id_alloc();
1010 if (dma_dom->domain.id == 0) 1092 if (dma_dom->domain.id == 0)
1011 goto free_dma_dom; 1093 goto free_dma_dom;
1012 dma_dom->domain.mode = PAGE_MODE_3_LEVEL; 1094 dma_dom->domain.mode = PAGE_MODE_2_LEVEL;
1013 dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); 1095 dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);
1014 dma_dom->domain.flags = PD_DMA_OPS_MASK; 1096 dma_dom->domain.flags = PD_DMA_OPS_MASK;
1015 dma_dom->domain.priv = dma_dom; 1097 dma_dom->domain.priv = dma_dom;
@@ -1063,6 +1145,41 @@ static struct protection_domain *domain_for_device(u16 devid)
1063 return dom; 1145 return dom;
1064} 1146}
1065 1147
1148static void set_dte_entry(u16 devid, struct protection_domain *domain)
1149{
1150 u64 pte_root = virt_to_phys(domain->pt_root);
1151
1152 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
1153 << DEV_ENTRY_MODE_SHIFT;
1154 pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;
1155
1156 amd_iommu_dev_table[devid].data[2] = domain->id;
1157 amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
1158 amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
1159
1160 amd_iommu_pd_table[devid] = domain;
1161}
1162
1163/*
1164 * If a device is not yet associated with a domain, this function does
1165 * assigns it visible for the hardware
1166 */
1167static void __attach_device(struct amd_iommu *iommu,
1168 struct protection_domain *domain,
1169 u16 devid)
1170{
1171 /* lock domain */
1172 spin_lock(&domain->lock);
1173
1174 /* update DTE entry */
1175 set_dte_entry(devid, domain);
1176
1177 domain->dev_cnt += 1;
1178
1179 /* ready */
1180 spin_unlock(&domain->lock);
1181}
1182
1066/* 1183/*
1067 * If a device is not yet associated with a domain, this function does 1184 * If a device is not yet associated with a domain, this function does
1068 * assigns it visible for the hardware 1185 * assigns it visible for the hardware
@@ -1072,27 +1189,16 @@ static void attach_device(struct amd_iommu *iommu,
1072 u16 devid) 1189 u16 devid)
1073{ 1190{
1074 unsigned long flags; 1191 unsigned long flags;
1075 u64 pte_root = virt_to_phys(domain->pt_root);
1076
1077 domain->dev_cnt += 1;
1078
1079 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
1080 << DEV_ENTRY_MODE_SHIFT;
1081 pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;
1082 1192
1083 write_lock_irqsave(&amd_iommu_devtable_lock, flags); 1193 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
1084 amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); 1194 __attach_device(iommu, domain, devid);
1085 amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
1086 amd_iommu_dev_table[devid].data[2] = domain->id;
1087
1088 amd_iommu_pd_table[devid] = domain;
1089 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); 1195 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
1090 1196
1091 /* 1197 /*
1092 * We might boot into a crash-kernel here. The crashed kernel 1198 * We might boot into a crash-kernel here. The crashed kernel
1093 * left the caches in the IOMMU dirty. So we have to flush 1199 * left the caches in the IOMMU dirty. So we have to flush
1094 * here to evict all dirty stuff. 1200 * here to evict all dirty stuff.
1095 */ 1201 */
1096 iommu_queue_inv_dev_entry(iommu, devid); 1202 iommu_queue_inv_dev_entry(iommu, devid);
1097 iommu_flush_tlb_pde(iommu, domain->id); 1203 iommu_flush_tlb_pde(iommu, domain->id);
1098} 1204}
@@ -1119,6 +1225,15 @@ static void __detach_device(struct protection_domain *domain, u16 devid)
1119 1225
1120 /* ready */ 1226 /* ready */
1121 spin_unlock(&domain->lock); 1227 spin_unlock(&domain->lock);
1228
1229 /*
1230 * If we run in passthrough mode the device must be assigned to the
1231 * passthrough domain if it is detached from any other domain
1232 */
1233 if (iommu_pass_through) {
1234 struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
1235 __attach_device(iommu, pt_domain, devid);
1236 }
1122} 1237}
1123 1238
1124/* 1239/*
@@ -1164,6 +1279,8 @@ static int device_change_notifier(struct notifier_block *nb,
1164 case BUS_NOTIFY_UNBOUND_DRIVER: 1279 case BUS_NOTIFY_UNBOUND_DRIVER:
1165 if (!domain) 1280 if (!domain)
1166 goto out; 1281 goto out;
1282 if (iommu_pass_through)
1283 break;
1167 detach_device(domain, devid); 1284 detach_device(domain, devid);
1168 break; 1285 break;
1169 case BUS_NOTIFY_ADD_DEVICE: 1286 case BUS_NOTIFY_ADD_DEVICE:
@@ -1292,39 +1409,91 @@ static int get_device_resources(struct device *dev,
1292 return 1; 1409 return 1;
1293} 1410}
1294 1411
1412static void update_device_table(struct protection_domain *domain)
1413{
1414 unsigned long flags;
1415 int i;
1416
1417 for (i = 0; i <= amd_iommu_last_bdf; ++i) {
1418 if (amd_iommu_pd_table[i] != domain)
1419 continue;
1420 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
1421 set_dte_entry(i, domain);
1422 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
1423 }
1424}
1425
1426static void update_domain(struct protection_domain *domain)
1427{
1428 if (!domain->updated)
1429 return;
1430
1431 update_device_table(domain);
1432 flush_devices_by_domain(domain);
1433 iommu_flush_domain(domain->id);
1434
1435 domain->updated = false;
1436}
1437
1295/* 1438/*
1296 * If the pte_page is not yet allocated this function is called 1439 * This function is used to add another level to an IO page table. Adding
1440 * another level increases the size of the address space by 9 bits to a size up
1441 * to 64 bits.
1297 */ 1442 */
1298static u64* alloc_pte(struct protection_domain *dom, 1443static bool increase_address_space(struct protection_domain *domain,
1299 unsigned long address, u64 **pte_page, gfp_t gfp) 1444 gfp_t gfp)
1445{
1446 u64 *pte;
1447
1448 if (domain->mode == PAGE_MODE_6_LEVEL)
1449 /* address space already 64 bit large */
1450 return false;
1451
1452 pte = (void *)get_zeroed_page(gfp);
1453 if (!pte)
1454 return false;
1455
1456 *pte = PM_LEVEL_PDE(domain->mode,
1457 virt_to_phys(domain->pt_root));
1458 domain->pt_root = pte;
1459 domain->mode += 1;
1460 domain->updated = true;
1461
1462 return true;
1463}
1464
1465static u64 *alloc_pte(struct protection_domain *domain,
1466 unsigned long address,
1467 int end_lvl,
1468 u64 **pte_page,
1469 gfp_t gfp)
1300{ 1470{
1301 u64 *pte, *page; 1471 u64 *pte, *page;
1472 int level;
1302 1473
1303 pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(address)]; 1474 while (address > PM_LEVEL_SIZE(domain->mode))
1475 increase_address_space(domain, gfp);
1304 1476
1305 if (!IOMMU_PTE_PRESENT(*pte)) { 1477 level = domain->mode - 1;
1306 page = (u64 *)get_zeroed_page(gfp); 1478 pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
1307 if (!page)
1308 return NULL;
1309 *pte = IOMMU_L2_PDE(virt_to_phys(page));
1310 }
1311 1479
1312 pte = IOMMU_PTE_PAGE(*pte); 1480 while (level > end_lvl) {
1313 pte = &pte[IOMMU_PTE_L1_INDEX(address)]; 1481 if (!IOMMU_PTE_PRESENT(*pte)) {
1482 page = (u64 *)get_zeroed_page(gfp);
1483 if (!page)
1484 return NULL;
1485 *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
1486 }
1314 1487
1315 if (!IOMMU_PTE_PRESENT(*pte)) { 1488 level -= 1;
1316 page = (u64 *)get_zeroed_page(gfp);
1317 if (!page)
1318 return NULL;
1319 *pte = IOMMU_L1_PDE(virt_to_phys(page));
1320 }
1321 1489
1322 pte = IOMMU_PTE_PAGE(*pte); 1490 pte = IOMMU_PTE_PAGE(*pte);
1323 1491
1324 if (pte_page) 1492 if (pte_page && level == end_lvl)
1325 *pte_page = pte; 1493 *pte_page = pte;
1326 1494
1327 pte = &pte[IOMMU_PTE_L0_INDEX(address)]; 1495 pte = &pte[PM_LEVEL_INDEX(level, address)];
1496 }
1328 1497
1329 return pte; 1498 return pte;
1330} 1499}
@@ -1344,10 +1513,13 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
1344 1513
1345 pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; 1514 pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)];
1346 if (!pte) { 1515 if (!pte) {
1347 pte = alloc_pte(&dom->domain, address, &pte_page, GFP_ATOMIC); 1516 pte = alloc_pte(&dom->domain, address, PM_MAP_4k, &pte_page,
1517 GFP_ATOMIC);
1348 aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page; 1518 aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page;
1349 } else 1519 } else
1350 pte += IOMMU_PTE_L0_INDEX(address); 1520 pte += PM_LEVEL_INDEX(0, address);
1521
1522 update_domain(&dom->domain);
1351 1523
1352 return pte; 1524 return pte;
1353} 1525}
@@ -1409,7 +1581,7 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu,
1409 if (!pte) 1581 if (!pte)
1410 return; 1582 return;
1411 1583
1412 pte += IOMMU_PTE_L0_INDEX(address); 1584 pte += PM_LEVEL_INDEX(0, address);
1413 1585
1414 WARN_ON(!*pte); 1586 WARN_ON(!*pte);
1415 1587
@@ -1988,19 +2160,47 @@ static void cleanup_domain(struct protection_domain *domain)
1988 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); 2160 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
1989} 2161}
1990 2162
1991static int amd_iommu_domain_init(struct iommu_domain *dom) 2163static void protection_domain_free(struct protection_domain *domain)
2164{
2165 if (!domain)
2166 return;
2167
2168 if (domain->id)
2169 domain_id_free(domain->id);
2170
2171 kfree(domain);
2172}
2173
2174static struct protection_domain *protection_domain_alloc(void)
1992{ 2175{
1993 struct protection_domain *domain; 2176 struct protection_domain *domain;
1994 2177
1995 domain = kzalloc(sizeof(*domain), GFP_KERNEL); 2178 domain = kzalloc(sizeof(*domain), GFP_KERNEL);
1996 if (!domain) 2179 if (!domain)
1997 return -ENOMEM; 2180 return NULL;
1998 2181
1999 spin_lock_init(&domain->lock); 2182 spin_lock_init(&domain->lock);
2000 domain->mode = PAGE_MODE_3_LEVEL;
2001 domain->id = domain_id_alloc(); 2183 domain->id = domain_id_alloc();
2002 if (!domain->id) 2184 if (!domain->id)
2185 goto out_err;
2186
2187 return domain;
2188
2189out_err:
2190 kfree(domain);
2191
2192 return NULL;
2193}
2194
2195static int amd_iommu_domain_init(struct iommu_domain *dom)
2196{
2197 struct protection_domain *domain;
2198
2199 domain = protection_domain_alloc();
2200 if (!domain)
2003 goto out_free; 2201 goto out_free;
2202
2203 domain->mode = PAGE_MODE_3_LEVEL;
2004 domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); 2204 domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL);
2005 if (!domain->pt_root) 2205 if (!domain->pt_root)
2006 goto out_free; 2206 goto out_free;
@@ -2010,7 +2210,7 @@ static int amd_iommu_domain_init(struct iommu_domain *dom)
2010 return 0; 2210 return 0;
2011 2211
2012out_free: 2212out_free:
2013 kfree(domain); 2213 protection_domain_free(domain);
2014 2214
2015 return -ENOMEM; 2215 return -ENOMEM;
2016} 2216}
@@ -2115,7 +2315,7 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
2115 paddr &= PAGE_MASK; 2315 paddr &= PAGE_MASK;
2116 2316
2117 for (i = 0; i < npages; ++i) { 2317 for (i = 0; i < npages; ++i) {
2118 ret = iommu_map_page(domain, iova, paddr, prot); 2318 ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
2119 if (ret) 2319 if (ret)
2120 return ret; 2320 return ret;
2121 2321
@@ -2136,7 +2336,7 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom,
2136 iova &= PAGE_MASK; 2336 iova &= PAGE_MASK;
2137 2337
2138 for (i = 0; i < npages; ++i) { 2338 for (i = 0; i < npages; ++i) {
2139 iommu_unmap_page(domain, iova); 2339 iommu_unmap_page(domain, iova, PM_MAP_4k);
2140 iova += PAGE_SIZE; 2340 iova += PAGE_SIZE;
2141 } 2341 }
2142 2342
@@ -2151,21 +2351,9 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
2151 phys_addr_t paddr; 2351 phys_addr_t paddr;
2152 u64 *pte; 2352 u64 *pte;
2153 2353
2154 pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(iova)]; 2354 pte = fetch_pte(domain, iova, PM_MAP_4k);
2155
2156 if (!IOMMU_PTE_PRESENT(*pte))
2157 return 0;
2158
2159 pte = IOMMU_PTE_PAGE(*pte);
2160 pte = &pte[IOMMU_PTE_L1_INDEX(iova)];
2161
2162 if (!IOMMU_PTE_PRESENT(*pte))
2163 return 0;
2164
2165 pte = IOMMU_PTE_PAGE(*pte);
2166 pte = &pte[IOMMU_PTE_L0_INDEX(iova)];
2167 2355
2168 if (!IOMMU_PTE_PRESENT(*pte)) 2356 if (!pte || !IOMMU_PTE_PRESENT(*pte))
2169 return 0; 2357 return 0;
2170 2358
2171 paddr = *pte & IOMMU_PAGE_MASK; 2359 paddr = *pte & IOMMU_PAGE_MASK;
@@ -2191,3 +2379,46 @@ static struct iommu_ops amd_iommu_ops = {
2191 .domain_has_cap = amd_iommu_domain_has_cap, 2379 .domain_has_cap = amd_iommu_domain_has_cap,
2192}; 2380};
2193 2381
2382/*****************************************************************************
2383 *
2384 * The next functions do a basic initialization of IOMMU for pass through
2385 * mode
2386 *
2387 * In passthrough mode the IOMMU is initialized and enabled but not used for
2388 * DMA-API translation.
2389 *
2390 *****************************************************************************/
2391
2392int __init amd_iommu_init_passthrough(void)
2393{
2394 struct pci_dev *dev = NULL;
2395 u16 devid, devid2;
2396
2397 /* allocate passthroug domain */
2398 pt_domain = protection_domain_alloc();
2399 if (!pt_domain)
2400 return -ENOMEM;
2401
2402 pt_domain->mode |= PAGE_MODE_NONE;
2403
2404 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
2405 struct amd_iommu *iommu;
2406
2407 devid = calc_devid(dev->bus->number, dev->devfn);
2408 if (devid > amd_iommu_last_bdf)
2409 continue;
2410
2411 devid2 = amd_iommu_alias_table[devid];
2412
2413 iommu = amd_iommu_rlookup_table[devid2];
2414 if (!iommu)
2415 continue;
2416
2417 __attach_device(iommu, pt_domain, devid);
2418 __attach_device(iommu, pt_domain, devid2);
2419 }
2420
2421 pr_info("AMD-Vi: Initialized for Passthrough Mode\n");
2422
2423 return 0;
2424}
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index c1b17e97252e..b4b61d462dcc 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -252,7 +252,7 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
252/* Function to enable the hardware */ 252/* Function to enable the hardware */
253static void iommu_enable(struct amd_iommu *iommu) 253static void iommu_enable(struct amd_iommu *iommu)
254{ 254{
255 printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n", 255 printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx\n",
256 dev_name(&iommu->dev->dev), iommu->cap_ptr); 256 dev_name(&iommu->dev->dev), iommu->cap_ptr);
257 257
258 iommu_feature_enable(iommu, CONTROL_IOMMU_EN); 258 iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
@@ -435,6 +435,20 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
435} 435}
436 436
437/* 437/*
438 * This function resets the command buffer if the IOMMU stopped fetching
439 * commands from it.
440 */
441void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu)
442{
443 iommu_feature_disable(iommu, CONTROL_CMDBUF_EN);
444
445 writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
446 writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
447
448 iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
449}
450
451/*
438 * This function writes the command buffer address to the hardware and 452 * This function writes the command buffer address to the hardware and
439 * enables it. 453 * enables it.
440 */ 454 */
@@ -450,11 +464,7 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
450 memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, 464 memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
451 &entry, sizeof(entry)); 465 &entry, sizeof(entry));
452 466
453 /* set head and tail to zero manually */ 467 amd_iommu_reset_cmd_buffer(iommu);
454 writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
455 writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
456
457 iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
458} 468}
459 469
460static void __init free_command_buffer(struct amd_iommu *iommu) 470static void __init free_command_buffer(struct amd_iommu *iommu)
@@ -858,7 +868,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
858 switch (*p) { 868 switch (*p) {
859 case ACPI_IVHD_TYPE: 869 case ACPI_IVHD_TYPE:
860 870
861 DUMP_printk("IOMMU: device: %02x:%02x.%01x cap: %04x " 871 DUMP_printk("device: %02x:%02x.%01x cap: %04x "
862 "seg: %d flags: %01x info %04x\n", 872 "seg: %d flags: %01x info %04x\n",
863 PCI_BUS(h->devid), PCI_SLOT(h->devid), 873 PCI_BUS(h->devid), PCI_SLOT(h->devid),
864 PCI_FUNC(h->devid), h->cap_ptr, 874 PCI_FUNC(h->devid), h->cap_ptr,
@@ -902,7 +912,7 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu)
902 912
903 r = request_irq(iommu->dev->irq, amd_iommu_int_handler, 913 r = request_irq(iommu->dev->irq, amd_iommu_int_handler,
904 IRQF_SAMPLE_RANDOM, 914 IRQF_SAMPLE_RANDOM,
905 "AMD IOMMU", 915 "AMD-Vi",
906 NULL); 916 NULL);
907 917
908 if (r) { 918 if (r) {
@@ -1150,7 +1160,7 @@ int __init amd_iommu_init(void)
1150 1160
1151 1161
1152 if (no_iommu) { 1162 if (no_iommu) {
1153 printk(KERN_INFO "AMD IOMMU disabled by kernel command line\n"); 1163 printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
1154 return 0; 1164 return 0;
1155 } 1165 }
1156 1166
@@ -1242,22 +1252,28 @@ int __init amd_iommu_init(void)
1242 if (ret) 1252 if (ret)
1243 goto free; 1253 goto free;
1244 1254
1245 ret = amd_iommu_init_dma_ops(); 1255 if (iommu_pass_through)
1256 ret = amd_iommu_init_passthrough();
1257 else
1258 ret = amd_iommu_init_dma_ops();
1246 if (ret) 1259 if (ret)
1247 goto free; 1260 goto free;
1248 1261
1249 enable_iommus(); 1262 enable_iommus();
1250 1263
1251 printk(KERN_INFO "AMD IOMMU: device isolation "); 1264 if (iommu_pass_through)
1265 goto out;
1266
1267 printk(KERN_INFO "AMD-Vi: device isolation ");
1252 if (amd_iommu_isolate) 1268 if (amd_iommu_isolate)
1253 printk("enabled\n"); 1269 printk("enabled\n");
1254 else 1270 else
1255 printk("disabled\n"); 1271 printk("disabled\n");
1256 1272
1257 if (amd_iommu_unmap_flush) 1273 if (amd_iommu_unmap_flush)
1258 printk(KERN_INFO "AMD IOMMU: IO/TLB flush on unmap enabled\n"); 1274 printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
1259 else 1275 else
1260 printk(KERN_INFO "AMD IOMMU: Lazy IO/TLB flushing enabled\n"); 1276 printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
1261 1277
1262out: 1278out:
1263 return ret; 1279 return ret;
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 676debfc1702..128111d8ffe0 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -20,6 +20,7 @@
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/suspend.h> 22#include <linux/suspend.h>
23#include <linux/kmemleak.h>
23#include <asm/e820.h> 24#include <asm/e820.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/iommu.h> 26#include <asm/iommu.h>
@@ -94,6 +95,11 @@ static u32 __init allocate_aperture(void)
94 * code for safe 95 * code for safe
95 */ 96 */
96 p = __alloc_bootmem_nopanic(aper_size, aper_size, 512ULL<<20); 97 p = __alloc_bootmem_nopanic(aper_size, aper_size, 512ULL<<20);
98 /*
99 * Kmemleak should not scan this block as it may not be mapped via the
100 * kernel direct mapping.
101 */
102 kmemleak_ignore(p);
97 if (!p || __pa(p)+aper_size > 0xffffffff) { 103 if (!p || __pa(p)+aper_size > 0xffffffff) {
98 printk(KERN_ERR 104 printk(KERN_ERR
99 "Cannot allocate aperture memory hole (%p,%uK)\n", 105 "Cannot allocate aperture memory hole (%p,%uK)\n",
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 0a1c2830ec66..159740decc41 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -49,6 +49,7 @@
49#include <asm/mtrr.h> 49#include <asm/mtrr.h>
50#include <asm/smp.h> 50#include <asm/smp.h>
51#include <asm/mce.h> 51#include <asm/mce.h>
52#include <asm/kvm_para.h>
52 53
53unsigned int num_processors; 54unsigned int num_processors;
54 55
@@ -1361,52 +1362,80 @@ void enable_x2apic(void)
1361} 1362}
1362#endif /* CONFIG_X86_X2APIC */ 1363#endif /* CONFIG_X86_X2APIC */
1363 1364
1364void __init enable_IR_x2apic(void) 1365int __init enable_IR(void)
1365{ 1366{
1366#ifdef CONFIG_INTR_REMAP 1367#ifdef CONFIG_INTR_REMAP
1367 int ret;
1368 unsigned long flags;
1369 struct IO_APIC_route_entry **ioapic_entries = NULL;
1370
1371 ret = dmar_table_init();
1372 if (ret) {
1373 pr_debug("dmar_table_init() failed with %d:\n", ret);
1374 goto ir_failed;
1375 }
1376
1377 if (!intr_remapping_supported()) { 1368 if (!intr_remapping_supported()) {
1378 pr_debug("intr-remapping not supported\n"); 1369 pr_debug("intr-remapping not supported\n");
1379 goto ir_failed; 1370 return 0;
1380 } 1371 }
1381 1372
1382
1383 if (!x2apic_preenabled && skip_ioapic_setup) { 1373 if (!x2apic_preenabled && skip_ioapic_setup) {
1384 pr_info("Skipped enabling intr-remap because of skipping " 1374 pr_info("Skipped enabling intr-remap because of skipping "
1385 "io-apic setup\n"); 1375 "io-apic setup\n");
1386 return; 1376 return 0;
1387 } 1377 }
1388 1378
1379 if (enable_intr_remapping(x2apic_supported()))
1380 return 0;
1381
1382 pr_info("Enabled Interrupt-remapping\n");
1383
1384 return 1;
1385
1386#endif
1387 return 0;
1388}
1389
1390void __init enable_IR_x2apic(void)
1391{
1392 unsigned long flags;
1393 struct IO_APIC_route_entry **ioapic_entries = NULL;
1394 int ret, x2apic_enabled = 0;
1395 int dmar_table_init_ret = 0;
1396
1397#ifdef CONFIG_INTR_REMAP
1398 dmar_table_init_ret = dmar_table_init();
1399 if (dmar_table_init_ret)
1400 pr_debug("dmar_table_init() failed with %d:\n",
1401 dmar_table_init_ret);
1402#endif
1403
1389 ioapic_entries = alloc_ioapic_entries(); 1404 ioapic_entries = alloc_ioapic_entries();
1390 if (!ioapic_entries) { 1405 if (!ioapic_entries) {
1391 pr_info("Allocate ioapic_entries failed: %d\n", ret); 1406 pr_err("Allocate ioapic_entries failed\n");
1392 goto end; 1407 goto out;
1393 } 1408 }
1394 1409
1395 ret = save_IO_APIC_setup(ioapic_entries); 1410 ret = save_IO_APIC_setup(ioapic_entries);
1396 if (ret) { 1411 if (ret) {
1397 pr_info("Saving IO-APIC state failed: %d\n", ret); 1412 pr_info("Saving IO-APIC state failed: %d\n", ret);
1398 goto end; 1413 goto out;
1399 } 1414 }
1400 1415
1401 local_irq_save(flags); 1416 local_irq_save(flags);
1402 mask_IO_APIC_setup(ioapic_entries);
1403 mask_8259A(); 1417 mask_8259A();
1418 mask_IO_APIC_setup(ioapic_entries);
1404 1419
1405 ret = enable_intr_remapping(x2apic_supported()); 1420 if (dmar_table_init_ret)
1406 if (ret) 1421 ret = 0;
1407 goto end_restore; 1422 else
1423 ret = enable_IR();
1408 1424
1409 pr_info("Enabled Interrupt-remapping\n"); 1425 if (!ret) {
1426 /* IR is required if there is APIC ID > 255 even when running
1427 * under KVM
1428 */
1429 if (max_physical_apicid > 255 || !kvm_para_available())
1430 goto nox2apic;
1431 /*
1432 * without IR all CPUs can be addressed by IOAPIC/MSI
1433 * only in physical mode
1434 */
1435 x2apic_force_phys();
1436 }
1437
1438 x2apic_enabled = 1;
1410 1439
1411 if (x2apic_supported() && !x2apic_mode) { 1440 if (x2apic_supported() && !x2apic_mode) {
1412 x2apic_mode = 1; 1441 x2apic_mode = 1;
@@ -1414,41 +1443,25 @@ void __init enable_IR_x2apic(void)
1414 pr_info("Enabled x2apic\n"); 1443 pr_info("Enabled x2apic\n");
1415 } 1444 }
1416 1445
1417end_restore: 1446nox2apic:
1418 if (ret) 1447 if (!ret) /* IR enabling failed */
1419 /*
1420 * IR enabling failed
1421 */
1422 restore_IO_APIC_setup(ioapic_entries); 1448 restore_IO_APIC_setup(ioapic_entries);
1423
1424 unmask_8259A(); 1449 unmask_8259A();
1425 local_irq_restore(flags); 1450 local_irq_restore(flags);
1426 1451
1427end: 1452out:
1428 if (ioapic_entries) 1453 if (ioapic_entries)
1429 free_ioapic_entries(ioapic_entries); 1454 free_ioapic_entries(ioapic_entries);
1430 1455
1431 if (!ret) 1456 if (x2apic_enabled)
1432 return; 1457 return;
1433 1458
1434ir_failed:
1435 if (x2apic_preenabled) 1459 if (x2apic_preenabled)
1436 panic("x2apic enabled by bios. But IR enabling failed"); 1460 panic("x2apic: enabled by BIOS but kernel init failed.");
1437 else if (cpu_has_x2apic) 1461 else if (cpu_has_x2apic)
1438 pr_info("Not enabling x2apic,Intr-remapping\n"); 1462 pr_info("Not enabling x2apic, Intr-remapping init failed.\n");
1439#else
1440 if (!cpu_has_x2apic)
1441 return;
1442
1443 if (x2apic_preenabled)
1444 panic("x2apic enabled prior OS handover,"
1445 " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP");
1446#endif
1447
1448 return;
1449} 1463}
1450 1464
1451
1452#ifdef CONFIG_X86_64 1465#ifdef CONFIG_X86_64
1453/* 1466/*
1454 * Detect and enable local APICs on non-SMP boards. 1467 * Detect and enable local APICs on non-SMP boards.
@@ -1549,8 +1562,6 @@ no_apic:
1549#ifdef CONFIG_X86_64 1562#ifdef CONFIG_X86_64
1550void __init early_init_lapic_mapping(void) 1563void __init early_init_lapic_mapping(void)
1551{ 1564{
1552 unsigned long phys_addr;
1553
1554 /* 1565 /*
1555 * If no local APIC can be found then go out 1566 * If no local APIC can be found then go out
1556 * : it means there is no mpatable and MADT 1567 * : it means there is no mpatable and MADT
@@ -1558,11 +1569,9 @@ void __init early_init_lapic_mapping(void)
1558 if (!smp_found_config) 1569 if (!smp_found_config)
1559 return; 1570 return;
1560 1571
1561 phys_addr = mp_lapic_addr; 1572 set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
1562
1563 set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
1564 apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", 1573 apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
1565 APIC_BASE, phys_addr); 1574 APIC_BASE, mp_lapic_addr);
1566 1575
1567 /* 1576 /*
1568 * Fetch the APIC ID of the BSP in case we have a 1577 * Fetch the APIC ID of the BSP in case we have a
@@ -1651,7 +1660,6 @@ int __init APIC_init_uniprocessor(void)
1651 APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { 1660 APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
1652 pr_err("BIOS bug, local APIC 0x%x not detected!...\n", 1661 pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
1653 boot_cpu_physical_apicid); 1662 boot_cpu_physical_apicid);
1654 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1655 return -1; 1663 return -1;
1656 } 1664 }
1657#endif 1665#endif
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 8952a5890281..89174f847b49 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -167,7 +167,7 @@ static int es7000_apic_is_cluster(void)
167{ 167{
168 /* MPENTIUMIII */ 168 /* MPENTIUMIII */
169 if (boot_cpu_data.x86 == 6 && 169 if (boot_cpu_data.x86 == 6 &&
170 (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) 170 (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
171 return 1; 171 return 1;
172 172
173 return 0; 173 return 0;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index d2ed6c5ddc80..3c8f9e75d038 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -66,6 +66,8 @@
66#include <asm/apic.h> 66#include <asm/apic.h>
67 67
68#define __apicdebuginit(type) static type __init 68#define __apicdebuginit(type) static type __init
69#define for_each_irq_pin(entry, head) \
70 for (entry = head; entry; entry = entry->next)
69 71
70/* 72/*
71 * Is the SiS APIC rmw bug present ? 73 * Is the SiS APIC rmw bug present ?
@@ -85,6 +87,9 @@ int nr_ioapic_registers[MAX_IO_APICS];
85struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; 87struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
86int nr_ioapics; 88int nr_ioapics;
87 89
90/* IO APIC gsi routing info */
91struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
92
88/* MP IRQ source entries */ 93/* MP IRQ source entries */
89struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; 94struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
90 95
@@ -116,15 +121,6 @@ static int __init parse_noapic(char *str)
116} 121}
117early_param("noapic", parse_noapic); 122early_param("noapic", parse_noapic);
118 123
119struct irq_pin_list;
120
121/*
122 * This is performance-critical, we want to do it O(1)
123 *
124 * the indexing order of this array favors 1:1 mappings
125 * between pins and IRQs.
126 */
127
128struct irq_pin_list { 124struct irq_pin_list {
129 int apic, pin; 125 int apic, pin;
130 struct irq_pin_list *next; 126 struct irq_pin_list *next;
@@ -139,6 +135,11 @@ static struct irq_pin_list *get_one_free_irq_2_pin(int node)
139 return pin; 135 return pin;
140} 136}
141 137
138/*
139 * This is performance-critical, we want to do it O(1)
140 *
141 * Most irqs are mapped 1:1 with pins.
142 */
142struct irq_cfg { 143struct irq_cfg {
143 struct irq_pin_list *irq_2_pin; 144 struct irq_pin_list *irq_2_pin;
144 cpumask_var_t domain; 145 cpumask_var_t domain;
@@ -414,13 +415,10 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
414 unsigned long flags; 415 unsigned long flags;
415 416
416 spin_lock_irqsave(&ioapic_lock, flags); 417 spin_lock_irqsave(&ioapic_lock, flags);
417 entry = cfg->irq_2_pin; 418 for_each_irq_pin(entry, cfg->irq_2_pin) {
418 for (;;) {
419 unsigned int reg; 419 unsigned int reg;
420 int pin; 420 int pin;
421 421
422 if (!entry)
423 break;
424 pin = entry->pin; 422 pin = entry->pin;
425 reg = io_apic_read(entry->apic, 0x10 + pin*2); 423 reg = io_apic_read(entry->apic, 0x10 + pin*2);
426 /* Is the remote IRR bit set? */ 424 /* Is the remote IRR bit set? */
@@ -428,9 +426,6 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
428 spin_unlock_irqrestore(&ioapic_lock, flags); 426 spin_unlock_irqrestore(&ioapic_lock, flags);
429 return true; 427 return true;
430 } 428 }
431 if (!entry->next)
432 break;
433 entry = entry->next;
434 } 429 }
435 spin_unlock_irqrestore(&ioapic_lock, flags); 430 spin_unlock_irqrestore(&ioapic_lock, flags);
436 431
@@ -498,72 +493,68 @@ static void ioapic_mask_entry(int apic, int pin)
498 * shared ISA-space IRQs, so we have to support them. We are super 493 * shared ISA-space IRQs, so we have to support them. We are super
499 * fast in the common case, and fast for shared ISA-space IRQs. 494 * fast in the common case, and fast for shared ISA-space IRQs.
500 */ 495 */
501static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin) 496static int
497add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin)
502{ 498{
503 struct irq_pin_list *entry; 499 struct irq_pin_list **last, *entry;
504 500
505 entry = cfg->irq_2_pin; 501 /* don't allow duplicates */
506 if (!entry) { 502 last = &cfg->irq_2_pin;
507 entry = get_one_free_irq_2_pin(node); 503 for_each_irq_pin(entry, cfg->irq_2_pin) {
508 if (!entry) {
509 printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
510 apic, pin);
511 return;
512 }
513 cfg->irq_2_pin = entry;
514 entry->apic = apic;
515 entry->pin = pin;
516 return;
517 }
518
519 while (entry->next) {
520 /* not again, please */
521 if (entry->apic == apic && entry->pin == pin) 504 if (entry->apic == apic && entry->pin == pin)
522 return; 505 return 0;
523 506 last = &entry->next;
524 entry = entry->next;
525 } 507 }
526 508
527 entry->next = get_one_free_irq_2_pin(node); 509 entry = get_one_free_irq_2_pin(node);
528 entry = entry->next; 510 if (!entry) {
511 printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n",
512 node, apic, pin);
513 return -ENOMEM;
514 }
529 entry->apic = apic; 515 entry->apic = apic;
530 entry->pin = pin; 516 entry->pin = pin;
517
518 *last = entry;
519 return 0;
520}
521
522static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
523{
524 if (add_pin_to_irq_node_nopanic(cfg, node, apic, pin))
525 panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
531} 526}
532 527
533/* 528/*
534 * Reroute an IRQ to a different pin. 529 * Reroute an IRQ to a different pin.
535 */ 530 */
536static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node, 531static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node,
537 int oldapic, int oldpin, 532 int oldapic, int oldpin,
538 int newapic, int newpin) 533 int newapic, int newpin)
539{ 534{
540 struct irq_pin_list *entry = cfg->irq_2_pin; 535 struct irq_pin_list *entry;
541 int replaced = 0;
542 536
543 while (entry) { 537 for_each_irq_pin(entry, cfg->irq_2_pin) {
544 if (entry->apic == oldapic && entry->pin == oldpin) { 538 if (entry->apic == oldapic && entry->pin == oldpin) {
545 entry->apic = newapic; 539 entry->apic = newapic;
546 entry->pin = newpin; 540 entry->pin = newpin;
547 replaced = 1;
548 /* every one is different, right? */ 541 /* every one is different, right? */
549 break; 542 return;
550 } 543 }
551 entry = entry->next;
552 } 544 }
553 545
554 /* why? call replace before add? */ 546 /* old apic/pin didn't exist, so just add new ones */
555 if (!replaced) 547 add_pin_to_irq_node(cfg, node, newapic, newpin);
556 add_pin_to_irq_node(cfg, node, newapic, newpin);
557} 548}
558 549
559static inline void io_apic_modify_irq(struct irq_cfg *cfg, 550static void io_apic_modify_irq(struct irq_cfg *cfg,
560 int mask_and, int mask_or, 551 int mask_and, int mask_or,
561 void (*final)(struct irq_pin_list *entry)) 552 void (*final)(struct irq_pin_list *entry))
562{ 553{
563 int pin; 554 int pin;
564 struct irq_pin_list *entry; 555 struct irq_pin_list *entry;
565 556
566 for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) { 557 for_each_irq_pin(entry, cfg->irq_2_pin) {
567 unsigned int reg; 558 unsigned int reg;
568 pin = entry->pin; 559 pin = entry->pin;
569 reg = io_apic_read(entry->apic, 0x10 + pin * 2); 560 reg = io_apic_read(entry->apic, 0x10 + pin * 2);
@@ -580,7 +571,6 @@ static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
580 io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); 571 io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
581} 572}
582 573
583#ifdef CONFIG_X86_64
584static void io_apic_sync(struct irq_pin_list *entry) 574static void io_apic_sync(struct irq_pin_list *entry)
585{ 575{
586 /* 576 /*
@@ -596,11 +586,6 @@ static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
596{ 586{
597 io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); 587 io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
598} 588}
599#else /* CONFIG_X86_32 */
600static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
601{
602 io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL);
603}
604 589
605static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg) 590static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg)
606{ 591{
@@ -613,7 +598,6 @@ static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg)
613 io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 598 io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED,
614 IO_APIC_REDIR_LEVEL_TRIGGER, NULL); 599 IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
615} 600}
616#endif /* CONFIG_X86_32 */
617 601
618static void mask_IO_APIC_irq_desc(struct irq_desc *desc) 602static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
619{ 603{
@@ -1702,12 +1686,8 @@ __apicdebuginit(void) print_IO_APIC(void)
1702 if (!entry) 1686 if (!entry)
1703 continue; 1687 continue;
1704 printk(KERN_DEBUG "IRQ%d ", irq); 1688 printk(KERN_DEBUG "IRQ%d ", irq);
1705 for (;;) { 1689 for_each_irq_pin(entry, cfg->irq_2_pin)
1706 printk("-> %d:%d", entry->apic, entry->pin); 1690 printk("-> %d:%d", entry->apic, entry->pin);
1707 if (!entry->next)
1708 break;
1709 entry = entry->next;
1710 }
1711 printk("\n"); 1691 printk("\n");
1712 } 1692 }
1713 1693
@@ -2211,7 +2191,6 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
2211 return was_pending; 2191 return was_pending;
2212} 2192}
2213 2193
2214#ifdef CONFIG_X86_64
2215static int ioapic_retrigger_irq(unsigned int irq) 2194static int ioapic_retrigger_irq(unsigned int irq)
2216{ 2195{
2217 2196
@@ -2224,14 +2203,6 @@ static int ioapic_retrigger_irq(unsigned int irq)
2224 2203
2225 return 1; 2204 return 1;
2226} 2205}
2227#else
2228static int ioapic_retrigger_irq(unsigned int irq)
2229{
2230 apic->send_IPI_self(irq_cfg(irq)->vector);
2231
2232 return 1;
2233}
2234#endif
2235 2206
2236/* 2207/*
2237 * Level and edge triggered IO-APIC interrupts need different handling, 2208 * Level and edge triggered IO-APIC interrupts need different handling,
@@ -2269,13 +2240,9 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
2269 struct irq_pin_list *entry; 2240 struct irq_pin_list *entry;
2270 u8 vector = cfg->vector; 2241 u8 vector = cfg->vector;
2271 2242
2272 entry = cfg->irq_2_pin; 2243 for_each_irq_pin(entry, cfg->irq_2_pin) {
2273 for (;;) {
2274 unsigned int reg; 2244 unsigned int reg;
2275 2245
2276 if (!entry)
2277 break;
2278
2279 apic = entry->apic; 2246 apic = entry->apic;
2280 pin = entry->pin; 2247 pin = entry->pin;
2281 /* 2248 /*
@@ -2288,9 +2255,6 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
2288 reg &= ~IO_APIC_REDIR_VECTOR_MASK; 2255 reg &= ~IO_APIC_REDIR_VECTOR_MASK;
2289 reg |= vector; 2256 reg |= vector;
2290 io_apic_modify(apic, 0x10 + pin*2, reg); 2257 io_apic_modify(apic, 0x10 + pin*2, reg);
2291 if (!entry->next)
2292 break;
2293 entry = entry->next;
2294 } 2258 }
2295} 2259}
2296 2260
@@ -2515,11 +2479,8 @@ atomic_t irq_mis_count;
2515static void ack_apic_level(unsigned int irq) 2479static void ack_apic_level(unsigned int irq)
2516{ 2480{
2517 struct irq_desc *desc = irq_to_desc(irq); 2481 struct irq_desc *desc = irq_to_desc(irq);
2518
2519#ifdef CONFIG_X86_32
2520 unsigned long v; 2482 unsigned long v;
2521 int i; 2483 int i;
2522#endif
2523 struct irq_cfg *cfg; 2484 struct irq_cfg *cfg;
2524 int do_unmask_irq = 0; 2485 int do_unmask_irq = 0;
2525 2486
@@ -2532,31 +2493,28 @@ static void ack_apic_level(unsigned int irq)
2532 } 2493 }
2533#endif 2494#endif
2534 2495
2535#ifdef CONFIG_X86_32
2536 /* 2496 /*
2537 * It appears there is an erratum which affects at least version 0x11 2497 * It appears there is an erratum which affects at least version 0x11
2538 * of I/O APIC (that's the 82093AA and cores integrated into various 2498 * of I/O APIC (that's the 82093AA and cores integrated into various
2539 * chipsets). Under certain conditions a level-triggered interrupt is 2499 * chipsets). Under certain conditions a level-triggered interrupt is
2540 * erroneously delivered as edge-triggered one but the respective IRR 2500 * erroneously delivered as edge-triggered one but the respective IRR
2541 * bit gets set nevertheless. As a result the I/O unit expects an EOI 2501 * bit gets set nevertheless. As a result the I/O unit expects an EOI
2542 * message but it will never arrive and further interrupts are blocked 2502 * message but it will never arrive and further interrupts are blocked
2543 * from the source. The exact reason is so far unknown, but the 2503 * from the source. The exact reason is so far unknown, but the
2544 * phenomenon was observed when two consecutive interrupt requests 2504 * phenomenon was observed when two consecutive interrupt requests
2545 * from a given source get delivered to the same CPU and the source is 2505 * from a given source get delivered to the same CPU and the source is
2546 * temporarily disabled in between. 2506 * temporarily disabled in between.
2547 * 2507 *
2548 * A workaround is to simulate an EOI message manually. We achieve it 2508 * A workaround is to simulate an EOI message manually. We achieve it
2549 * by setting the trigger mode to edge and then to level when the edge 2509 * by setting the trigger mode to edge and then to level when the edge
2550 * trigger mode gets detected in the TMR of a local APIC for a 2510 * trigger mode gets detected in the TMR of a local APIC for a
2551 * level-triggered interrupt. We mask the source for the time of the 2511 * level-triggered interrupt. We mask the source for the time of the
2552 * operation to prevent an edge-triggered interrupt escaping meanwhile. 2512 * operation to prevent an edge-triggered interrupt escaping meanwhile.
2553 * The idea is from Manfred Spraul. --macro 2513 * The idea is from Manfred Spraul. --macro
2554 */ 2514 */
2555 cfg = desc->chip_data; 2515 cfg = desc->chip_data;
2556 i = cfg->vector; 2516 i = cfg->vector;
2557
2558 v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); 2517 v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
2559#endif
2560 2518
2561 /* 2519 /*
2562 * We must acknowledge the irq before we move it or the acknowledge will 2520 * We must acknowledge the irq before we move it or the acknowledge will
@@ -2598,7 +2556,7 @@ static void ack_apic_level(unsigned int irq)
2598 unmask_IO_APIC_irq_desc(desc); 2556 unmask_IO_APIC_irq_desc(desc);
2599 } 2557 }
2600 2558
2601#ifdef CONFIG_X86_32 2559 /* Tail end of version 0x11 I/O APIC bug workaround */
2602 if (!(v & (1 << (i & 0x1f)))) { 2560 if (!(v & (1 << (i & 0x1f)))) {
2603 atomic_inc(&irq_mis_count); 2561 atomic_inc(&irq_mis_count);
2604 spin_lock(&ioapic_lock); 2562 spin_lock(&ioapic_lock);
@@ -2606,26 +2564,15 @@ static void ack_apic_level(unsigned int irq)
2606 __unmask_and_level_IO_APIC_irq(cfg); 2564 __unmask_and_level_IO_APIC_irq(cfg);
2607 spin_unlock(&ioapic_lock); 2565 spin_unlock(&ioapic_lock);
2608 } 2566 }
2609#endif
2610} 2567}
2611 2568
2612#ifdef CONFIG_INTR_REMAP 2569#ifdef CONFIG_INTR_REMAP
2613static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) 2570static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
2614{ 2571{
2615 int apic, pin;
2616 struct irq_pin_list *entry; 2572 struct irq_pin_list *entry;
2617 2573
2618 entry = cfg->irq_2_pin; 2574 for_each_irq_pin(entry, cfg->irq_2_pin)
2619 for (;;) { 2575 io_apic_eoi(entry->apic, entry->pin);
2620
2621 if (!entry)
2622 break;
2623
2624 apic = entry->apic;
2625 pin = entry->pin;
2626 io_apic_eoi(apic, pin);
2627 entry = entry->next;
2628 }
2629} 2576}
2630 2577
2631static void 2578static void
@@ -3241,8 +3188,7 @@ void destroy_irq(unsigned int irq)
3241 cfg = desc->chip_data; 3188 cfg = desc->chip_data;
3242 dynamic_irq_cleanup(irq); 3189 dynamic_irq_cleanup(irq);
3243 /* connect back irq_cfg */ 3190 /* connect back irq_cfg */
3244 if (desc) 3191 desc->chip_data = cfg;
3245 desc->chip_data = cfg;
3246 3192
3247 free_irte(irq); 3193 free_irte(irq);
3248 spin_lock_irqsave(&vector_lock, flags); 3194 spin_lock_irqsave(&vector_lock, flags);
@@ -3912,7 +3858,11 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
3912 */ 3858 */
3913 if (irq >= NR_IRQS_LEGACY) { 3859 if (irq >= NR_IRQS_LEGACY) {
3914 cfg = desc->chip_data; 3860 cfg = desc->chip_data;
3915 add_pin_to_irq_node(cfg, node, ioapic, pin); 3861 if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
3862 printk(KERN_INFO "can not add pin %d for irq %d\n",
3863 pin, irq);
3864 return 0;
3865 }
3916 } 3866 }
3917 3867
3918 setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity); 3868 setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
@@ -3941,11 +3891,28 @@ int io_apic_set_pci_routing(struct device *dev, int irq,
3941 return __io_apic_set_pci_routing(dev, irq, irq_attr); 3891 return __io_apic_set_pci_routing(dev, irq, irq_attr);
3942} 3892}
3943 3893
3944/* -------------------------------------------------------------------------- 3894u8 __init io_apic_unique_id(u8 id)
3945 ACPI-based IOAPIC Configuration 3895{
3946 -------------------------------------------------------------------------- */ 3896#ifdef CONFIG_X86_32
3897 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
3898 !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
3899 return io_apic_get_unique_id(nr_ioapics, id);
3900 else
3901 return id;
3902#else
3903 int i;
3904 DECLARE_BITMAP(used, 256);
3947 3905
3948#ifdef CONFIG_ACPI 3906 bitmap_zero(used, 256);
3907 for (i = 0; i < nr_ioapics; i++) {
3908 struct mpc_ioapic *ia = &mp_ioapics[i];
3909 __set_bit(ia->apicid, used);
3910 }
3911 if (!test_bit(id, used))
3912 return id;
3913 return find_first_zero_bit(used, 256);
3914#endif
3915}
3949 3916
3950#ifdef CONFIG_X86_32 3917#ifdef CONFIG_X86_32
3951int __init io_apic_get_unique_id(int ioapic, int apic_id) 3918int __init io_apic_get_unique_id(int ioapic, int apic_id)
@@ -4054,8 +4021,6 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
4054 return 0; 4021 return 0;
4055} 4022}
4056 4023
4057#endif /* CONFIG_ACPI */
4058
4059/* 4024/*
4060 * This function currently is only a helper for the i386 smp boot process where 4025 * This function currently is only a helper for the i386 smp boot process where
4061 * we need to reprogram the ioredtbls to cater for the cpus which have come online 4026 * we need to reprogram the ioredtbls to cater for the cpus which have come online
@@ -4109,7 +4074,7 @@ void __init setup_ioapic_dest(void)
4109 4074
4110static struct resource *ioapic_resources; 4075static struct resource *ioapic_resources;
4111 4076
4112static struct resource * __init ioapic_setup_resources(void) 4077static struct resource * __init ioapic_setup_resources(int nr_ioapics)
4113{ 4078{
4114 unsigned long n; 4079 unsigned long n;
4115 struct resource *res; 4080 struct resource *res;
@@ -4125,15 +4090,13 @@ static struct resource * __init ioapic_setup_resources(void)
4125 mem = alloc_bootmem(n); 4090 mem = alloc_bootmem(n);
4126 res = (void *)mem; 4091 res = (void *)mem;
4127 4092
4128 if (mem != NULL) { 4093 mem += sizeof(struct resource) * nr_ioapics;
4129 mem += sizeof(struct resource) * nr_ioapics;
4130 4094
4131 for (i = 0; i < nr_ioapics; i++) { 4095 for (i = 0; i < nr_ioapics; i++) {
4132 res[i].name = mem; 4096 res[i].name = mem;
4133 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; 4097 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
4134 sprintf(mem, "IOAPIC %u", i); 4098 sprintf(mem, "IOAPIC %u", i);
4135 mem += IOAPIC_RESOURCE_NAME_SIZE; 4099 mem += IOAPIC_RESOURCE_NAME_SIZE;
4136 }
4137 } 4100 }
4138 4101
4139 ioapic_resources = res; 4102 ioapic_resources = res;
@@ -4147,7 +4110,7 @@ void __init ioapic_init_mappings(void)
4147 struct resource *ioapic_res; 4110 struct resource *ioapic_res;
4148 int i; 4111 int i;
4149 4112
4150 ioapic_res = ioapic_setup_resources(); 4113 ioapic_res = ioapic_setup_resources(nr_ioapics);
4151 for (i = 0; i < nr_ioapics; i++) { 4114 for (i = 0; i < nr_ioapics; i++) {
4152 if (smp_found_config) { 4115 if (smp_found_config) {
4153 ioapic_phys = mp_ioapics[i].apicaddr; 4116 ioapic_phys = mp_ioapics[i].apicaddr;
@@ -4176,11 +4139,9 @@ fake_ioapic_page:
4176 __fix_to_virt(idx), ioapic_phys); 4139 __fix_to_virt(idx), ioapic_phys);
4177 idx++; 4140 idx++;
4178 4141
4179 if (ioapic_res != NULL) { 4142 ioapic_res->start = ioapic_phys;
4180 ioapic_res->start = ioapic_phys; 4143 ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
4181 ioapic_res->end = ioapic_phys + (4 * 1024) - 1; 4144 ioapic_res++;
4182 ioapic_res++;
4183 }
4184 } 4145 }
4185} 4146}
4186 4147
@@ -4201,3 +4162,76 @@ void __init ioapic_insert_resources(void)
4201 r++; 4162 r++;
4202 } 4163 }
4203} 4164}
4165
4166int mp_find_ioapic(int gsi)
4167{
4168 int i = 0;
4169
4170 /* Find the IOAPIC that manages this GSI. */
4171 for (i = 0; i < nr_ioapics; i++) {
4172 if ((gsi >= mp_gsi_routing[i].gsi_base)
4173 && (gsi <= mp_gsi_routing[i].gsi_end))
4174 return i;
4175 }
4176
4177 printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
4178 return -1;
4179}
4180
4181int mp_find_ioapic_pin(int ioapic, int gsi)
4182{
4183 if (WARN_ON(ioapic == -1))
4184 return -1;
4185 if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end))
4186 return -1;
4187
4188 return gsi - mp_gsi_routing[ioapic].gsi_base;
4189}
4190
4191static int bad_ioapic(unsigned long address)
4192{
4193 if (nr_ioapics >= MAX_IO_APICS) {
4194 printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded "
4195 "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics);
4196 return 1;
4197 }
4198 if (!address) {
4199 printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address"
4200 " found in table, skipping!\n");
4201 return 1;
4202 }
4203 return 0;
4204}
4205
4206void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
4207{
4208 int idx = 0;
4209
4210 if (bad_ioapic(address))
4211 return;
4212
4213 idx = nr_ioapics;
4214
4215 mp_ioapics[idx].type = MP_IOAPIC;
4216 mp_ioapics[idx].flags = MPC_APIC_USABLE;
4217 mp_ioapics[idx].apicaddr = address;
4218
4219 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
4220 mp_ioapics[idx].apicid = io_apic_unique_id(id);
4221 mp_ioapics[idx].apicver = io_apic_get_version(idx);
4222
4223 /*
4224 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
4225 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
4226 */
4227 mp_gsi_routing[idx].gsi_base = gsi_base;
4228 mp_gsi_routing[idx].gsi_end = gsi_base +
4229 io_apic_get_redir_entries(idx);
4230
4231 printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
4232 "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
4233 mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
4234 mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end);
4235
4236 nr_ioapics++;
4237}
diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c
index 6ef00ba4c886..08385e090a6f 100644
--- a/arch/x86/kernel/apic/ipi.c
+++ b/arch/x86/kernel/apic/ipi.c
@@ -153,7 +153,7 @@ int safe_smp_processor_id(void)
153{ 153{
154 int apicid, cpuid; 154 int apicid, cpuid;
155 155
156 if (!boot_cpu_has(X86_FEATURE_APIC)) 156 if (!cpu_has_apic)
157 return 0; 157 return 0;
158 158
159 apicid = hard_smp_processor_id(); 159 apicid = hard_smp_processor_id();
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index b3025b43b63a..db7220220d09 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -39,7 +39,7 @@
39int unknown_nmi_panic; 39int unknown_nmi_panic;
40int nmi_watchdog_enabled; 40int nmi_watchdog_enabled;
41 41
42static cpumask_var_t backtrace_mask; 42static cpumask_t backtrace_mask __read_mostly;
43 43
44/* nmi_active: 44/* nmi_active:
45 * >0: the lapic NMI watchdog is active, but can be disabled 45 * >0: the lapic NMI watchdog is active, but can be disabled
@@ -138,7 +138,6 @@ int __init check_nmi_watchdog(void)
138 if (!prev_nmi_count) 138 if (!prev_nmi_count)
139 goto error; 139 goto error;
140 140
141 alloc_cpumask_var(&backtrace_mask, GFP_KERNEL|__GFP_ZERO);
142 printk(KERN_INFO "Testing NMI watchdog ... "); 141 printk(KERN_INFO "Testing NMI watchdog ... ");
143 142
144#ifdef CONFIG_SMP 143#ifdef CONFIG_SMP
@@ -415,14 +414,17 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
415 } 414 }
416 415
417 /* We can be called before check_nmi_watchdog, hence NULL check. */ 416 /* We can be called before check_nmi_watchdog, hence NULL check. */
418 if (backtrace_mask != NULL && cpumask_test_cpu(cpu, backtrace_mask)) { 417 if (cpumask_test_cpu(cpu, &backtrace_mask)) {
419 static DEFINE_SPINLOCK(lock); /* Serialise the printks */ 418 static DEFINE_SPINLOCK(lock); /* Serialise the printks */
420 419
421 spin_lock(&lock); 420 spin_lock(&lock);
422 printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); 421 printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
422 show_regs(regs);
423 dump_stack(); 423 dump_stack();
424 spin_unlock(&lock); 424 spin_unlock(&lock);
425 cpumask_clear_cpu(cpu, backtrace_mask); 425 cpumask_clear_cpu(cpu, &backtrace_mask);
426
427 rc = 1;
426 } 428 }
427 429
428 /* Could check oops_in_progress here too, but it's safer not to */ 430 /* Could check oops_in_progress here too, but it's safer not to */
@@ -552,14 +554,18 @@ int do_nmi_callback(struct pt_regs *regs, int cpu)
552 return 0; 554 return 0;
553} 555}
554 556
555void __trigger_all_cpu_backtrace(void) 557void arch_trigger_all_cpu_backtrace(void)
556{ 558{
557 int i; 559 int i;
558 560
559 cpumask_copy(backtrace_mask, cpu_online_mask); 561 cpumask_copy(&backtrace_mask, cpu_online_mask);
562
563 printk(KERN_INFO "sending NMI to all CPUs:\n");
564 apic->send_IPI_all(NMI_VECTOR);
565
560 /* Wait for up to 10 seconds for all CPUs to do the backtrace */ 566 /* Wait for up to 10 seconds for all CPUs to do the backtrace */
561 for (i = 0; i < 10 * 1000; i++) { 567 for (i = 0; i < 10 * 1000; i++) {
562 if (cpumask_empty(backtrace_mask)) 568 if (cpumask_empty(&backtrace_mask))
563 break; 569 break;
564 mdelay(1); 570 mdelay(1);
565 } 571 }
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index fcec2f1d34a1..65edc180fc82 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -55,11 +55,11 @@ static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
55void __init default_setup_apic_routing(void) 55void __init default_setup_apic_routing(void)
56{ 56{
57#ifdef CONFIG_X86_X2APIC 57#ifdef CONFIG_X86_X2APIC
58 if (x2apic_mode && (apic != &apic_x2apic_phys && 58 if (x2apic_mode
59#ifdef CONFIG_X86_UV 59#ifdef CONFIG_X86_UV
60 apic != &apic_x2apic_uv_x && 60 && apic != &apic_x2apic_uv_x
61#endif 61#endif
62 apic != &apic_x2apic_cluster)) { 62 ) {
63 if (x2apic_phys) 63 if (x2apic_phys)
64 apic = &apic_x2apic_phys; 64 apic = &apic_x2apic_phys;
65 else 65 else
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 442b5508893f..151ace69a5aa 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -403,7 +403,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
403static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); 403static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
404static struct apm_user *user_list; 404static struct apm_user *user_list;
405static DEFINE_SPINLOCK(user_list_lock); 405static DEFINE_SPINLOCK(user_list_lock);
406static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } }; 406
407/*
408 * Set up a segment that references the real mode segment 0x40
409 * that extends up to the end of page zero (that we have reserved).
410 * This is for buggy BIOS's that refer to (real mode) segment 0x40
411 * even though they are called in protected mode.
412 */
413static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
414 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
407 415
408static const char driver_version[] = "1.16ac"; /* no spaces */ 416static const char driver_version[] = "1.16ac"; /* no spaces */
409 417
@@ -2332,15 +2340,6 @@ static int __init apm_init(void)
2332 pm_flags |= PM_APM; 2340 pm_flags |= PM_APM;
2333 2341
2334 /* 2342 /*
2335 * Set up a segment that references the real mode segment 0x40
2336 * that extends up to the end of page zero (that we have reserved).
2337 * This is for buggy BIOS's that refer to (real mode) segment 0x40
2338 * even though they are called in protected mode.
2339 */
2340 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
2341 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
2342
2343 /*
2344 * Set up the long jump entry point to the APM BIOS, which is called 2343 * Set up the long jump entry point to the APM BIOS, which is called
2345 * from inline assembly. 2344 * from inline assembly.
2346 */ 2345 */
@@ -2358,12 +2357,12 @@ static int __init apm_init(void)
2358 * code to that CPU. 2357 * code to that CPU.
2359 */ 2358 */
2360 gdt = get_cpu_gdt_table(0); 2359 gdt = get_cpu_gdt_table(0);
2361 set_base(gdt[APM_CS >> 3], 2360 set_desc_base(&gdt[APM_CS >> 3],
2362 __va((unsigned long)apm_info.bios.cseg << 4)); 2361 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
2363 set_base(gdt[APM_CS_16 >> 3], 2362 set_desc_base(&gdt[APM_CS_16 >> 3],
2364 __va((unsigned long)apm_info.bios.cseg_16 << 4)); 2363 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
2365 set_base(gdt[APM_DS >> 3], 2364 set_desc_base(&gdt[APM_DS >> 3],
2366 __va((unsigned long)apm_info.bios.dseg << 4)); 2365 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
2367 2366
2368 proc_create("apm", 0, NULL, &apm_file_ops); 2367 proc_create("apm", 0, NULL, &apm_file_ops);
2369 2368
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 63fddcd082cd..22a47c82f3c0 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -2,7 +2,7 @@
2#include <linux/bitops.h> 2#include <linux/bitops.h>
3#include <linux/mm.h> 3#include <linux/mm.h>
4 4
5#include <asm/io.h> 5#include <linux/io.h>
6#include <asm/processor.h> 6#include <asm/processor.h>
7#include <asm/apic.h> 7#include <asm/apic.h>
8#include <asm/cpu.h> 8#include <asm/cpu.h>
@@ -45,8 +45,8 @@ static void __cpuinit init_amd_k5(struct cpuinfo_x86 *c)
45#define CBAR_ENB (0x80000000) 45#define CBAR_ENB (0x80000000)
46#define CBAR_KEY (0X000000CB) 46#define CBAR_KEY (0X000000CB)
47 if (c->x86_model == 9 || c->x86_model == 10) { 47 if (c->x86_model == 9 || c->x86_model == 10) {
48 if (inl (CBAR) & CBAR_ENB) 48 if (inl(CBAR) & CBAR_ENB)
49 outl (0 | CBAR_KEY, CBAR); 49 outl(0 | CBAR_KEY, CBAR);
50 } 50 }
51} 51}
52 52
@@ -87,9 +87,10 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
87 d = d2-d; 87 d = d2-d;
88 88
89 if (d > 20*K6_BUG_LOOP) 89 if (d > 20*K6_BUG_LOOP)
90 printk("system stability may be impaired when more than 32 MB are used.\n"); 90 printk(KERN_CONT
91 "system stability may be impaired when more than 32 MB are used.\n");
91 else 92 else
92 printk("probably OK (after B9730xxxx).\n"); 93 printk(KERN_CONT "probably OK (after B9730xxxx).\n");
93 printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n"); 94 printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n");
94 } 95 }
95 96
@@ -219,8 +220,9 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
219 if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { 220 if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
220 rdmsr(MSR_K7_CLK_CTL, l, h); 221 rdmsr(MSR_K7_CLK_CTL, l, h);
221 if ((l & 0xfff00000) != 0x20000000) { 222 if ((l & 0xfff00000) != 0x20000000) {
222 printk ("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", l, 223 printk(KERN_INFO
223 ((l & 0x000fffff)|0x20000000)); 224 "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
225 l, ((l & 0x000fffff)|0x20000000));
224 wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h); 226 wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
225 } 227 }
226 } 228 }
@@ -251,6 +253,64 @@ static int __cpuinit nearby_node(int apicid)
251#endif 253#endif
252 254
253/* 255/*
256 * Fixup core topology information for AMD multi-node processors.
257 * Assumption 1: Number of cores in each internal node is the same.
258 * Assumption 2: Mixed systems with both single-node and dual-node
259 * processors are not supported.
260 */
261#ifdef CONFIG_X86_HT
262static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
263{
264#ifdef CONFIG_PCI
265 u32 t, cpn;
266 u8 n, n_id;
267 int cpu = smp_processor_id();
268
269 /* fixup topology information only once for a core */
270 if (cpu_has(c, X86_FEATURE_AMD_DCM))
271 return;
272
273 /* check for multi-node processor on boot cpu */
274 t = read_pci_config(0, 24, 3, 0xe8);
275 if (!(t & (1 << 29)))
276 return;
277
278 set_cpu_cap(c, X86_FEATURE_AMD_DCM);
279
280 /* cores per node: each internal node has half the number of cores */
281 cpn = c->x86_max_cores >> 1;
282
283 /* even-numbered NB_id of this dual-node processor */
284 n = c->phys_proc_id << 1;
285
286 /*
287 * determine internal node id and assign cores fifty-fifty to
288 * each node of the dual-node processor
289 */
290 t = read_pci_config(0, 24 + n, 3, 0xe8);
291 n = (t>>30) & 0x3;
292 if (n == 0) {
293 if (c->cpu_core_id < cpn)
294 n_id = 0;
295 else
296 n_id = 1;
297 } else {
298 if (c->cpu_core_id < cpn)
299 n_id = 1;
300 else
301 n_id = 0;
302 }
303
304 /* compute entire NodeID, use llc_shared_map to store sibling info */
305 per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
306
307 /* fixup core id to be in range from 0 to cpn */
308 c->cpu_core_id = c->cpu_core_id % cpn;
309#endif
310}
311#endif
312
313/*
254 * On a AMD dual core setup the lower bits of the APIC id distingush the cores. 314 * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
255 * Assumes number of cores is a power of two. 315 * Assumes number of cores is a power of two.
256 */ 316 */
@@ -267,6 +327,9 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
267 c->phys_proc_id = c->initial_apicid >> bits; 327 c->phys_proc_id = c->initial_apicid >> bits;
268 /* use socket ID also for last level cache */ 328 /* use socket ID also for last level cache */
269 per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; 329 per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
330 /* fixup topology information on multi-node processors */
331 if ((c->x86 == 0x10) && (c->x86_model == 9))
332 amd_fixup_dcm(c);
270#endif 333#endif
271} 334}
272 335
@@ -275,9 +338,10 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
275#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) 338#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
276 int cpu = smp_processor_id(); 339 int cpu = smp_processor_id();
277 int node; 340 int node;
278 unsigned apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid; 341 unsigned apicid = c->apicid;
342
343 node = per_cpu(cpu_llc_id, cpu);
279 344
280 node = c->phys_proc_id;
281 if (apicid_to_node[apicid] != NUMA_NO_NODE) 345 if (apicid_to_node[apicid] != NUMA_NO_NODE)
282 node = apicid_to_node[apicid]; 346 node = apicid_to_node[apicid];
283 if (!node_online(node)) { 347 if (!node_online(node)) {
@@ -398,18 +462,30 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
398 u32 level; 462 u32 level;
399 463
400 level = cpuid_eax(1); 464 level = cpuid_eax(1);
401 if((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58) 465 if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
402 set_cpu_cap(c, X86_FEATURE_REP_GOOD); 466 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
403 467
404 /* 468 /*
405 * Some BIOSes incorrectly force this feature, but only K8 469 * Some BIOSes incorrectly force this feature, but only K8
406 * revision D (model = 0x14) and later actually support it. 470 * revision D (model = 0x14) and later actually support it.
471 * (AMD Erratum #110, docId: 25759).
407 */ 472 */
408 if (c->x86_model < 0x14) 473 if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) {
474 u64 val;
475
409 clear_cpu_cap(c, X86_FEATURE_LAHF_LM); 476 clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
477 if (!rdmsrl_amd_safe(0xc001100d, &val)) {
478 val &= ~(1ULL << 32);
479 wrmsrl_amd_safe(0xc001100d, val);
480 }
481 }
482
410 } 483 }
411 if (c->x86 == 0x10 || c->x86 == 0x11) 484 if (c->x86 == 0x10 || c->x86 == 0x11)
412 set_cpu_cap(c, X86_FEATURE_REP_GOOD); 485 set_cpu_cap(c, X86_FEATURE_REP_GOOD);
486
487 /* get apicid instead of initial apic id from cpuid */
488 c->apicid = hard_smp_processor_id();
413#else 489#else
414 490
415 /* 491 /*
@@ -494,27 +570,30 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
494 * benefit in doing so. 570 * benefit in doing so.
495 */ 571 */
496 if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { 572 if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
497 printk(KERN_DEBUG "tseg: %010llx\n", tseg); 573 printk(KERN_DEBUG "tseg: %010llx\n", tseg);
498 if ((tseg>>PMD_SHIFT) < 574 if ((tseg>>PMD_SHIFT) <
499 (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) || 575 (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) ||
500 ((tseg>>PMD_SHIFT) < 576 ((tseg>>PMD_SHIFT) <
501 (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) && 577 (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) &&
502 (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT)))) 578 (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
503 set_memory_4k((unsigned long)__va(tseg), 1); 579 set_memory_4k((unsigned long)__va(tseg), 1);
504 } 580 }
505 } 581 }
506#endif 582#endif
507} 583}
508 584
509#ifdef CONFIG_X86_32 585#ifdef CONFIG_X86_32
510static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size) 586static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
587 unsigned int size)
511{ 588{
512 /* AMD errata T13 (order #21922) */ 589 /* AMD errata T13 (order #21922) */
513 if ((c->x86 == 6)) { 590 if ((c->x86 == 6)) {
514 if (c->x86_model == 3 && c->x86_mask == 0) /* Duron Rev A0 */ 591 /* Duron Rev A0 */
592 if (c->x86_model == 3 && c->x86_mask == 0)
515 size = 64; 593 size = 64;
594 /* Tbird rev A1/A2 */
516 if (c->x86_model == 4 && 595 if (c->x86_model == 4 &&
517 (c->x86_mask == 0 || c->x86_mask == 1)) /* Tbird rev A1/A2 */ 596 (c->x86_mask == 0 || c->x86_mask == 1))
518 size = 256; 597 size = 256;
519 } 598 }
520 return size; 599 return size;
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index c8e315f1aa83..01a265212395 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -81,7 +81,7 @@ static void __init check_fpu(void)
81 81
82 boot_cpu_data.fdiv_bug = fdiv_bug; 82 boot_cpu_data.fdiv_bug = fdiv_bug;
83 if (boot_cpu_data.fdiv_bug) 83 if (boot_cpu_data.fdiv_bug)
84 printk("Hmm, FPU with FDIV bug.\n"); 84 printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n");
85} 85}
86 86
87static void __init check_hlt(void) 87static void __init check_hlt(void)
@@ -98,7 +98,7 @@ static void __init check_hlt(void)
98 halt(); 98 halt();
99 halt(); 99 halt();
100 halt(); 100 halt();
101 printk("OK.\n"); 101 printk(KERN_CONT "OK.\n");
102} 102}
103 103
104/* 104/*
@@ -122,9 +122,9 @@ static void __init check_popad(void)
122 * CPU hard. Too bad. 122 * CPU hard. Too bad.
123 */ 123 */
124 if (res != 12345678) 124 if (res != 12345678)
125 printk("Buggy.\n"); 125 printk(KERN_CONT "Buggy.\n");
126 else 126 else
127 printk("OK.\n"); 127 printk(KERN_CONT "OK.\n");
128#endif 128#endif
129} 129}
130 130
@@ -156,7 +156,7 @@ void __init check_bugs(void)
156{ 156{
157 identify_boot_cpu(); 157 identify_boot_cpu();
158#ifndef CONFIG_SMP 158#ifndef CONFIG_SMP
159 printk("CPU: "); 159 printk(KERN_INFO "CPU: ");
160 print_cpu_info(&boot_cpu_data); 160 print_cpu_info(&boot_cpu_data);
161#endif 161#endif
162 check_config(); 162 check_config();
diff --git a/arch/x86/kernel/cpu/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c
index 9a3ed0649d4e..04f0fe5af83e 100644
--- a/arch/x86/kernel/cpu/bugs_64.c
+++ b/arch/x86/kernel/cpu/bugs_64.c
@@ -15,7 +15,7 @@ void __init check_bugs(void)
15{ 15{
16 identify_boot_cpu(); 16 identify_boot_cpu();
17#if !defined(CONFIG_SMP) 17#if !defined(CONFIG_SMP)
18 printk("CPU: "); 18 printk(KERN_INFO "CPU: ");
19 print_cpu_info(&boot_cpu_data); 19 print_cpu_info(&boot_cpu_data);
20#endif 20#endif
21 alternative_instructions(); 21 alternative_instructions();
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 5ce60a88027b..2055fc2b2e6b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -18,8 +18,8 @@
18#include <asm/hypervisor.h> 18#include <asm/hypervisor.h>
19#include <asm/processor.h> 19#include <asm/processor.h>
20#include <asm/sections.h> 20#include <asm/sections.h>
21#include <asm/topology.h> 21#include <linux/topology.h>
22#include <asm/cpumask.h> 22#include <linux/cpumask.h>
23#include <asm/pgtable.h> 23#include <asm/pgtable.h>
24#include <asm/atomic.h> 24#include <asm/atomic.h>
25#include <asm/proto.h> 25#include <asm/proto.h>
@@ -28,13 +28,13 @@
28#include <asm/desc.h> 28#include <asm/desc.h>
29#include <asm/i387.h> 29#include <asm/i387.h>
30#include <asm/mtrr.h> 30#include <asm/mtrr.h>
31#include <asm/numa.h> 31#include <linux/numa.h>
32#include <asm/asm.h> 32#include <asm/asm.h>
33#include <asm/cpu.h> 33#include <asm/cpu.h>
34#include <asm/mce.h> 34#include <asm/mce.h>
35#include <asm/msr.h> 35#include <asm/msr.h>
36#include <asm/pat.h> 36#include <asm/pat.h>
37#include <asm/smp.h> 37#include <linux/smp.h>
38 38
39#ifdef CONFIG_X86_LOCAL_APIC 39#ifdef CONFIG_X86_LOCAL_APIC
40#include <asm/uv/uv.h> 40#include <asm/uv/uv.h>
@@ -94,45 +94,45 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
94 * TLS descriptors are currently at a different place compared to i386. 94 * TLS descriptors are currently at a different place compared to i386.
95 * Hopefully nobody expects them at a fixed place (Wine?) 95 * Hopefully nobody expects them at a fixed place (Wine?)
96 */ 96 */
97 [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, 97 [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
98 [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, 98 [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
99 [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, 99 [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
100 [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, 100 [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
101 [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, 101 [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
102 [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, 102 [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
103#else 103#else
104 [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, 104 [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
105 [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, 105 [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
106 [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, 106 [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
107 [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, 107 [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
108 /* 108 /*
109 * Segments used for calling PnP BIOS have byte granularity. 109 * Segments used for calling PnP BIOS have byte granularity.
110 * They code segments and data segments have fixed 64k limits, 110 * They code segments and data segments have fixed 64k limits,
111 * the transfer segment sizes are set at run time. 111 * the transfer segment sizes are set at run time.
112 */ 112 */
113 /* 32-bit code */ 113 /* 32-bit code */
114 [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, 114 [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
115 /* 16-bit code */ 115 /* 16-bit code */
116 [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, 116 [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
117 /* 16-bit data */ 117 /* 16-bit data */
118 [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, 118 [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff),
119 /* 16-bit data */ 119 /* 16-bit data */
120 [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, 120 [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0),
121 /* 16-bit data */ 121 /* 16-bit data */
122 [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, 122 [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0),
123 /* 123 /*
124 * The APM segments have byte granularity and their bases 124 * The APM segments have byte granularity and their bases
125 * are set at run time. All have 64k limits. 125 * are set at run time. All have 64k limits.
126 */ 126 */
127 /* 32-bit code */ 127 /* 32-bit code */
128 [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, 128 [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
129 /* 16-bit code */ 129 /* 16-bit code */
130 [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, 130 [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
131 /* data */ 131 /* data */
132 [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, 132 [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff),
133 133
134 [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } }, 134 [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
135 [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, 135 [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
136 GDT_STACK_CANARY_INIT 136 GDT_STACK_CANARY_INIT
137#endif 137#endif
138} }; 138} };
@@ -982,18 +982,26 @@ static __init int setup_disablecpuid(char *arg)
982__setup("clearcpuid=", setup_disablecpuid); 982__setup("clearcpuid=", setup_disablecpuid);
983 983
984#ifdef CONFIG_X86_64 984#ifdef CONFIG_X86_64
985struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; 985struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table };
986 986
987DEFINE_PER_CPU_FIRST(union irq_stack_union, 987DEFINE_PER_CPU_FIRST(union irq_stack_union,
988 irq_stack_union) __aligned(PAGE_SIZE); 988 irq_stack_union) __aligned(PAGE_SIZE);
989 989
990DEFINE_PER_CPU(char *, irq_stack_ptr) = 990/*
991 init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; 991 * The following four percpu variables are hot. Align current_task to
992 * cacheline size such that all four fall in the same cacheline.
993 */
994DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
995 &init_task;
996EXPORT_PER_CPU_SYMBOL(current_task);
992 997
993DEFINE_PER_CPU(unsigned long, kernel_stack) = 998DEFINE_PER_CPU(unsigned long, kernel_stack) =
994 (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; 999 (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
995EXPORT_PER_CPU_SYMBOL(kernel_stack); 1000EXPORT_PER_CPU_SYMBOL(kernel_stack);
996 1001
1002DEFINE_PER_CPU(char *, irq_stack_ptr) =
1003 init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
1004
997DEFINE_PER_CPU(unsigned int, irq_count) = -1; 1005DEFINE_PER_CPU(unsigned int, irq_count) = -1;
998 1006
999/* 1007/*
@@ -1008,8 +1016,7 @@ static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = {
1008}; 1016};
1009 1017
1010static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks 1018static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
1011 [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) 1019 [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]);
1012 __aligned(PAGE_SIZE);
1013 1020
1014/* May not be marked __init: used by software suspend */ 1021/* May not be marked __init: used by software suspend */
1015void syscall_init(void) 1022void syscall_init(void)
@@ -1042,8 +1049,11 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist);
1042 1049
1043#else /* CONFIG_X86_64 */ 1050#else /* CONFIG_X86_64 */
1044 1051
1052DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
1053EXPORT_PER_CPU_SYMBOL(current_task);
1054
1045#ifdef CONFIG_CC_STACKPROTECTOR 1055#ifdef CONFIG_CC_STACKPROTECTOR
1046DEFINE_PER_CPU(unsigned long, stack_canary); 1056DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
1047#endif 1057#endif
1048 1058
1049/* Make sure %fs and %gs are initialized properly in idle threads */ 1059/* Make sure %fs and %gs are initialized properly in idle threads */
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 593171e967ef..19807b89f058 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -3,10 +3,10 @@
3#include <linux/delay.h> 3#include <linux/delay.h>
4#include <linux/pci.h> 4#include <linux/pci.h>
5#include <asm/dma.h> 5#include <asm/dma.h>
6#include <asm/io.h> 6#include <linux/io.h>
7#include <asm/processor-cyrix.h> 7#include <asm/processor-cyrix.h>
8#include <asm/processor-flags.h> 8#include <asm/processor-flags.h>
9#include <asm/timer.h> 9#include <linux/timer.h>
10#include <asm/pci-direct.h> 10#include <asm/pci-direct.h>
11#include <asm/tsc.h> 11#include <asm/tsc.h>
12 12
@@ -282,7 +282,8 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
282 * The 5510/5520 companion chips have a funky PIT. 282 * The 5510/5520 companion chips have a funky PIT.
283 */ 283 */
284 if (vendor == PCI_VENDOR_ID_CYRIX && 284 if (vendor == PCI_VENDOR_ID_CYRIX &&
285 (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) 285 (device == PCI_DEVICE_ID_CYRIX_5510 ||
286 device == PCI_DEVICE_ID_CYRIX_5520))
286 mark_tsc_unstable("cyrix 5510/5520 detected"); 287 mark_tsc_unstable("cyrix 5510/5520 detected");
287 } 288 }
288#endif 289#endif
@@ -299,7 +300,8 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
299 * ? : 0x7x 300 * ? : 0x7x
300 * GX1 : 0x8x GX1 datasheet 56 301 * GX1 : 0x8x GX1 datasheet 56
301 */ 302 */
302 if ((0x30 <= dir1 && dir1 <= 0x6f) || (0x80 <= dir1 && dir1 <= 0x8f)) 303 if ((0x30 <= dir1 && dir1 <= 0x6f) ||
304 (0x80 <= dir1 && dir1 <= 0x8f))
303 geode_configure(); 305 geode_configure();
304 return; 306 return;
305 } else { /* MediaGX */ 307 } else { /* MediaGX */
@@ -427,9 +429,12 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c)
427 printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n"); 429 printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n");
428 local_irq_save(flags); 430 local_irq_save(flags);
429 ccr3 = getCx86(CX86_CCR3); 431 ccr3 = getCx86(CX86_CCR3);
430 setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ 432 /* enable MAPEN */
431 setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80); /* enable cpuid */ 433 setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
432 setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ 434 /* enable cpuid */
435 setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80);
436 /* disable MAPEN */
437 setCx86(CX86_CCR3, ccr3);
433 local_irq_restore(flags); 438 local_irq_restore(flags);
434 } 439 }
435 } 440 }
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index fb5b86af0b01..93ba8eeb100a 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -28,11 +28,10 @@
28static inline void __cpuinit 28static inline void __cpuinit
29detect_hypervisor_vendor(struct cpuinfo_x86 *c) 29detect_hypervisor_vendor(struct cpuinfo_x86 *c)
30{ 30{
31 if (vmware_platform()) { 31 if (vmware_platform())
32 c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; 32 c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
33 } else { 33 else
34 c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; 34 c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
35 }
36} 35}
37 36
38unsigned long get_hypervisor_tsc_freq(void) 37unsigned long get_hypervisor_tsc_freq(void)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 3260ab044996..80a722a071b5 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -7,17 +7,17 @@
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/thread_info.h> 8#include <linux/thread_info.h>
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/uaccess.h>
10 11
11#include <asm/processor.h> 12#include <asm/processor.h>
12#include <asm/pgtable.h> 13#include <asm/pgtable.h>
13#include <asm/msr.h> 14#include <asm/msr.h>
14#include <asm/uaccess.h>
15#include <asm/ds.h> 15#include <asm/ds.h>
16#include <asm/bugs.h> 16#include <asm/bugs.h>
17#include <asm/cpu.h> 17#include <asm/cpu.h>
18 18
19#ifdef CONFIG_X86_64 19#ifdef CONFIG_X86_64
20#include <asm/topology.h> 20#include <linux/topology.h>
21#include <asm/numa_64.h> 21#include <asm/numa_64.h>
22#endif 22#endif
23 23
@@ -174,7 +174,8 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
174#ifdef CONFIG_X86_F00F_BUG 174#ifdef CONFIG_X86_F00F_BUG
175 /* 175 /*
176 * All current models of Pentium and Pentium with MMX technology CPUs 176 * All current models of Pentium and Pentium with MMX technology CPUs
177 * have the F0 0F bug, which lets nonprivileged users lock up the system. 177 * have the F0 0F bug, which lets nonprivileged users lock up the
178 * system.
178 * Note that the workaround only should be initialized once... 179 * Note that the workaround only should be initialized once...
179 */ 180 */
180 c->f00f_bug = 0; 181 c->f00f_bug = 0;
@@ -207,7 +208,7 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
207 printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); 208 printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n");
208 printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); 209 printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n");
209 lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE; 210 lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE;
210 wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); 211 wrmsr(MSR_IA32_MISC_ENABLE, lo, hi);
211 } 212 }
212 } 213 }
213 214
@@ -283,7 +284,7 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
283 /* Intel has a non-standard dependency on %ecx for this CPUID level. */ 284 /* Intel has a non-standard dependency on %ecx for this CPUID level. */
284 cpuid_count(4, 0, &eax, &ebx, &ecx, &edx); 285 cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
285 if (eax & 0x1f) 286 if (eax & 0x1f)
286 return ((eax >> 26) + 1); 287 return (eax >> 26) + 1;
287 else 288 else
288 return 1; 289 return 1;
289} 290}
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 789efe217e1a..804c40e2bc3e 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Changes: 4 * Changes:
5 * Venkatesh Pallipadi : Adding cache identification through cpuid(4) 5 * Venkatesh Pallipadi : Adding cache identification through cpuid(4)
6 * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure. 6 * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
7 * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD. 7 * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD.
8 */ 8 */
9 9
@@ -16,7 +16,7 @@
16#include <linux/pci.h> 16#include <linux/pci.h>
17 17
18#include <asm/processor.h> 18#include <asm/processor.h>
19#include <asm/smp.h> 19#include <linux/smp.h>
20#include <asm/k8.h> 20#include <asm/k8.h>
21 21
22#define LVL_1_INST 1 22#define LVL_1_INST 1
@@ -25,14 +25,15 @@
25#define LVL_3 4 25#define LVL_3 4
26#define LVL_TRACE 5 26#define LVL_TRACE 5
27 27
28struct _cache_table 28struct _cache_table {
29{
30 unsigned char descriptor; 29 unsigned char descriptor;
31 char cache_type; 30 char cache_type;
32 short size; 31 short size;
33}; 32};
34 33
35/* all the cache descriptor types we care about (no TLB or trace cache entries) */ 34/* All the cache descriptor types we care about (no TLB or
35 trace cache entries) */
36
36static const struct _cache_table __cpuinitconst cache_table[] = 37static const struct _cache_table __cpuinitconst cache_table[] =
37{ 38{
38 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ 39 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
@@ -105,8 +106,7 @@ static const struct _cache_table __cpuinitconst cache_table[] =
105}; 106};
106 107
107 108
108enum _cache_type 109enum _cache_type {
109{
110 CACHE_TYPE_NULL = 0, 110 CACHE_TYPE_NULL = 0,
111 CACHE_TYPE_DATA = 1, 111 CACHE_TYPE_DATA = 1,
112 CACHE_TYPE_INST = 2, 112 CACHE_TYPE_INST = 2,
@@ -170,31 +170,31 @@ unsigned short num_cache_leaves;
170 Maybe later */ 170 Maybe later */
171union l1_cache { 171union l1_cache {
172 struct { 172 struct {
173 unsigned line_size : 8; 173 unsigned line_size:8;
174 unsigned lines_per_tag : 8; 174 unsigned lines_per_tag:8;
175 unsigned assoc : 8; 175 unsigned assoc:8;
176 unsigned size_in_kb : 8; 176 unsigned size_in_kb:8;
177 }; 177 };
178 unsigned val; 178 unsigned val;
179}; 179};
180 180
181union l2_cache { 181union l2_cache {
182 struct { 182 struct {
183 unsigned line_size : 8; 183 unsigned line_size:8;
184 unsigned lines_per_tag : 4; 184 unsigned lines_per_tag:4;
185 unsigned assoc : 4; 185 unsigned assoc:4;
186 unsigned size_in_kb : 16; 186 unsigned size_in_kb:16;
187 }; 187 };
188 unsigned val; 188 unsigned val;
189}; 189};
190 190
191union l3_cache { 191union l3_cache {
192 struct { 192 struct {
193 unsigned line_size : 8; 193 unsigned line_size:8;
194 unsigned lines_per_tag : 4; 194 unsigned lines_per_tag:4;
195 unsigned assoc : 4; 195 unsigned assoc:4;
196 unsigned res : 2; 196 unsigned res:2;
197 unsigned size_encoded : 14; 197 unsigned size_encoded:14;
198 }; 198 };
199 unsigned val; 199 unsigned val;
200}; 200};
@@ -241,7 +241,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
241 case 0: 241 case 0:
242 if (!l1->val) 242 if (!l1->val)
243 return; 243 return;
244 assoc = l1->assoc; 244 assoc = assocs[l1->assoc];
245 line_size = l1->line_size; 245 line_size = l1->line_size;
246 lines_per_tag = l1->lines_per_tag; 246 lines_per_tag = l1->lines_per_tag;
247 size_in_kb = l1->size_in_kb; 247 size_in_kb = l1->size_in_kb;
@@ -249,7 +249,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
249 case 2: 249 case 2:
250 if (!l2.val) 250 if (!l2.val)
251 return; 251 return;
252 assoc = l2.assoc; 252 assoc = assocs[l2.assoc];
253 line_size = l2.line_size; 253 line_size = l2.line_size;
254 lines_per_tag = l2.lines_per_tag; 254 lines_per_tag = l2.lines_per_tag;
255 /* cpu_data has errata corrections for K7 applied */ 255 /* cpu_data has errata corrections for K7 applied */
@@ -258,10 +258,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
258 case 3: 258 case 3:
259 if (!l3.val) 259 if (!l3.val)
260 return; 260 return;
261 assoc = l3.assoc; 261 assoc = assocs[l3.assoc];
262 line_size = l3.line_size; 262 line_size = l3.line_size;
263 lines_per_tag = l3.lines_per_tag; 263 lines_per_tag = l3.lines_per_tag;
264 size_in_kb = l3.size_encoded * 512; 264 size_in_kb = l3.size_encoded * 512;
265 if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
266 size_in_kb = size_in_kb >> 1;
267 assoc = assoc >> 1;
268 }
265 break; 269 break;
266 default: 270 default:
267 return; 271 return;
@@ -270,18 +274,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
270 eax->split.is_self_initializing = 1; 274 eax->split.is_self_initializing = 1;
271 eax->split.type = types[leaf]; 275 eax->split.type = types[leaf];
272 eax->split.level = levels[leaf]; 276 eax->split.level = levels[leaf];
273 if (leaf == 3) 277 eax->split.num_threads_sharing = 0;
274 eax->split.num_threads_sharing =
275 current_cpu_data.x86_max_cores - 1;
276 else
277 eax->split.num_threads_sharing = 0;
278 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; 278 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
279 279
280 280
281 if (assoc == 0xf) 281 if (assoc == 0xffff)
282 eax->split.is_fully_associative = 1; 282 eax->split.is_fully_associative = 1;
283 ebx->split.coherency_line_size = line_size - 1; 283 ebx->split.coherency_line_size = line_size - 1;
284 ebx->split.ways_of_associativity = assocs[assoc] - 1; 284 ebx->split.ways_of_associativity = assoc - 1;
285 ebx->split.physical_line_partition = lines_per_tag - 1; 285 ebx->split.physical_line_partition = lines_per_tag - 1;
286 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size / 286 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
287 (ebx->split.ways_of_associativity + 1) - 1; 287 (ebx->split.ways_of_associativity + 1) - 1;
@@ -350,7 +350,8 @@ static int __cpuinit find_num_cache_leaves(void)
350 350
351unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) 351unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
352{ 352{
353 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ 353 /* Cache sizes */
354 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
354 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ 355 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
355 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ 356 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
356 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; 357 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
@@ -377,8 +378,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
377 378
378 retval = cpuid4_cache_lookup_regs(i, &this_leaf); 379 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
379 if (retval >= 0) { 380 if (retval >= 0) {
380 switch(this_leaf.eax.split.level) { 381 switch (this_leaf.eax.split.level) {
381 case 1: 382 case 1:
382 if (this_leaf.eax.split.type == 383 if (this_leaf.eax.split.type ==
383 CACHE_TYPE_DATA) 384 CACHE_TYPE_DATA)
384 new_l1d = this_leaf.size/1024; 385 new_l1d = this_leaf.size/1024;
@@ -386,19 +387,20 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
386 CACHE_TYPE_INST) 387 CACHE_TYPE_INST)
387 new_l1i = this_leaf.size/1024; 388 new_l1i = this_leaf.size/1024;
388 break; 389 break;
389 case 2: 390 case 2:
390 new_l2 = this_leaf.size/1024; 391 new_l2 = this_leaf.size/1024;
391 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; 392 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
392 index_msb = get_count_order(num_threads_sharing); 393 index_msb = get_count_order(num_threads_sharing);
393 l2_id = c->apicid >> index_msb; 394 l2_id = c->apicid >> index_msb;
394 break; 395 break;
395 case 3: 396 case 3:
396 new_l3 = this_leaf.size/1024; 397 new_l3 = this_leaf.size/1024;
397 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; 398 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
398 index_msb = get_count_order(num_threads_sharing); 399 index_msb = get_count_order(
400 num_threads_sharing);
399 l3_id = c->apicid >> index_msb; 401 l3_id = c->apicid >> index_msb;
400 break; 402 break;
401 default: 403 default:
402 break; 404 break;
403 } 405 }
404 } 406 }
@@ -421,22 +423,21 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
421 /* Number of times to iterate */ 423 /* Number of times to iterate */
422 n = cpuid_eax(2) & 0xFF; 424 n = cpuid_eax(2) & 0xFF;
423 425
424 for ( i = 0 ; i < n ; i++ ) { 426 for (i = 0 ; i < n ; i++) {
425 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]); 427 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
426 428
427 /* If bit 31 is set, this is an unknown format */ 429 /* If bit 31 is set, this is an unknown format */
428 for ( j = 0 ; j < 3 ; j++ ) { 430 for (j = 0 ; j < 3 ; j++)
429 if (regs[j] & (1 << 31)) regs[j] = 0; 431 if (regs[j] & (1 << 31))
430 } 432 regs[j] = 0;
431 433
432 /* Byte 0 is level count, not a descriptor */ 434 /* Byte 0 is level count, not a descriptor */
433 for ( j = 1 ; j < 16 ; j++ ) { 435 for (j = 1 ; j < 16 ; j++) {
434 unsigned char des = dp[j]; 436 unsigned char des = dp[j];
435 unsigned char k = 0; 437 unsigned char k = 0;
436 438
437 /* look up this descriptor in the table */ 439 /* look up this descriptor in the table */
438 while (cache_table[k].descriptor != 0) 440 while (cache_table[k].descriptor != 0) {
439 {
440 if (cache_table[k].descriptor == des) { 441 if (cache_table[k].descriptor == des) {
441 if (only_trace && cache_table[k].cache_type != LVL_TRACE) 442 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
442 break; 443 break;
@@ -488,14 +489,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
488 } 489 }
489 490
490 if (trace) 491 if (trace)
491 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); 492 printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
492 else if ( l1i ) 493 else if (l1i)
493 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); 494 printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
494 495
495 if (l1d) 496 if (l1d)
496 printk(", L1 D cache: %dK\n", l1d); 497 printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
497 else 498 else
498 printk("\n"); 499 printk(KERN_CONT "\n");
499 500
500 if (l2) 501 if (l2)
501 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); 502 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
@@ -522,6 +523,18 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
522 int index_msb, i; 523 int index_msb, i;
523 struct cpuinfo_x86 *c = &cpu_data(cpu); 524 struct cpuinfo_x86 *c = &cpu_data(cpu);
524 525
526 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
527 struct cpuinfo_x86 *d;
528 for_each_online_cpu(i) {
529 if (!per_cpu(cpuid4_info, i))
530 continue;
531 d = &cpu_data(i);
532 this_leaf = CPUID4_INFO_IDX(i, index);
533 cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
534 d->llc_shared_map);
535 }
536 return;
537 }
525 this_leaf = CPUID4_INFO_IDX(cpu, index); 538 this_leaf = CPUID4_INFO_IDX(cpu, index);
526 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; 539 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
527 540
@@ -558,8 +571,13 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
558 } 571 }
559} 572}
560#else 573#else
561static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {} 574static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
562static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {} 575{
576}
577
578static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
579{
580}
563#endif 581#endif
564 582
565static void __cpuinit free_cache_attributes(unsigned int cpu) 583static void __cpuinit free_cache_attributes(unsigned int cpu)
@@ -645,7 +663,7 @@ static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
645static ssize_t show_##file_name \ 663static ssize_t show_##file_name \
646 (struct _cpuid4_info *this_leaf, char *buf) \ 664 (struct _cpuid4_info *this_leaf, char *buf) \
647{ \ 665{ \
648 return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \ 666 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
649} 667}
650 668
651show_one_plus(level, eax.split.level, 0); 669show_one_plus(level, eax.split.level, 0);
@@ -656,7 +674,7 @@ show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
656 674
657static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf) 675static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
658{ 676{
659 return sprintf (buf, "%luK\n", this_leaf->size / 1024); 677 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
660} 678}
661 679
662static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, 680static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
@@ -669,7 +687,7 @@ static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
669 const struct cpumask *mask; 687 const struct cpumask *mask;
670 688
671 mask = to_cpumask(this_leaf->shared_cpu_map); 689 mask = to_cpumask(this_leaf->shared_cpu_map);
672 n = type? 690 n = type ?
673 cpulist_scnprintf(buf, len-2, mask) : 691 cpulist_scnprintf(buf, len-2, mask) :
674 cpumask_scnprintf(buf, len-2, mask); 692 cpumask_scnprintf(buf, len-2, mask);
675 buf[n++] = '\n'; 693 buf[n++] = '\n';
@@ -800,7 +818,7 @@ static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
800static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, 818static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
801 show_cache_disable_1, store_cache_disable_1); 819 show_cache_disable_1, store_cache_disable_1);
802 820
803static struct attribute * default_attrs[] = { 821static struct attribute *default_attrs[] = {
804 &type.attr, 822 &type.attr,
805 &level.attr, 823 &level.attr,
806 &coherency_line_size.attr, 824 &coherency_line_size.attr,
@@ -815,7 +833,7 @@ static struct attribute * default_attrs[] = {
815 NULL 833 NULL
816}; 834};
817 835
818static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf) 836static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
819{ 837{
820 struct _cache_attr *fattr = to_attr(attr); 838 struct _cache_attr *fattr = to_attr(attr);
821 struct _index_kobject *this_leaf = to_object(kobj); 839 struct _index_kobject *this_leaf = to_object(kobj);
@@ -828,8 +846,8 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
828 return ret; 846 return ret;
829} 847}
830 848
831static ssize_t store(struct kobject * kobj, struct attribute * attr, 849static ssize_t store(struct kobject *kobj, struct attribute *attr,
832 const char * buf, size_t count) 850 const char *buf, size_t count)
833{ 851{
834 struct _cache_attr *fattr = to_attr(attr); 852 struct _cache_attr *fattr = to_attr(attr);
835 struct _index_kobject *this_leaf = to_object(kobj); 853 struct _index_kobject *this_leaf = to_object(kobj);
@@ -883,7 +901,7 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
883 goto err_out; 901 goto err_out;
884 902
885 per_cpu(index_kobject, cpu) = kzalloc( 903 per_cpu(index_kobject, cpu) = kzalloc(
886 sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); 904 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
887 if (unlikely(per_cpu(index_kobject, cpu) == NULL)) 905 if (unlikely(per_cpu(index_kobject, cpu) == NULL))
888 goto err_out; 906 goto err_out;
889 907
@@ -917,7 +935,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
917 } 935 }
918 936
919 for (i = 0; i < num_cache_leaves; i++) { 937 for (i = 0; i < num_cache_leaves; i++) {
920 this_object = INDEX_KOBJECT_PTR(cpu,i); 938 this_object = INDEX_KOBJECT_PTR(cpu, i);
921 this_object->cpu = cpu; 939 this_object->cpu = cpu;
922 this_object->index = i; 940 this_object->index = i;
923 retval = kobject_init_and_add(&(this_object->kobj), 941 retval = kobject_init_and_add(&(this_object->kobj),
@@ -925,9 +943,8 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
925 per_cpu(cache_kobject, cpu), 943 per_cpu(cache_kobject, cpu),
926 "index%1lu", i); 944 "index%1lu", i);
927 if (unlikely(retval)) { 945 if (unlikely(retval)) {
928 for (j = 0; j < i; j++) { 946 for (j = 0; j < i; j++)
929 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj)); 947 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
930 }
931 kobject_put(per_cpu(cache_kobject, cpu)); 948 kobject_put(per_cpu(cache_kobject, cpu));
932 cpuid4_cache_sysfs_exit(cpu); 949 cpuid4_cache_sysfs_exit(cpu);
933 return retval; 950 return retval;
@@ -952,7 +969,7 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
952 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); 969 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
953 970
954 for (i = 0; i < num_cache_leaves; i++) 971 for (i = 0; i < num_cache_leaves; i++)
955 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); 972 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
956 kobject_put(per_cpu(cache_kobject, cpu)); 973 kobject_put(per_cpu(cache_kobject, cpu));
957 cpuid4_cache_sysfs_exit(cpu); 974 cpuid4_cache_sysfs_exit(cpu);
958} 975}
@@ -977,8 +994,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
977 return NOTIFY_OK; 994 return NOTIFY_OK;
978} 995}
979 996
980static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = 997static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
981{
982 .notifier_call = cacheinfo_cpu_callback, 998 .notifier_call = cacheinfo_cpu_callback,
983}; 999};
984 1000
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 01213048f62f..9bfe9d2ea615 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -183,6 +183,11 @@ void mce_log(struct mce *mce)
183 set_bit(0, &mce_need_notify); 183 set_bit(0, &mce_need_notify);
184} 184}
185 185
186void __weak decode_mce(struct mce *m)
187{
188 return;
189}
190
186static void print_mce(struct mce *m) 191static void print_mce(struct mce *m)
187{ 192{
188 printk(KERN_EMERG 193 printk(KERN_EMERG
@@ -205,6 +210,8 @@ static void print_mce(struct mce *m)
205 printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", 210 printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
206 m->cpuvendor, m->cpuid, m->time, m->socketid, 211 m->cpuvendor, m->cpuid, m->time, m->socketid,
207 m->apicid); 212 m->apicid);
213
214 decode_mce(m);
208} 215}
209 216
210static void print_mce_head(void) 217static void print_mce_head(void)
@@ -215,7 +222,10 @@ static void print_mce_head(void)
215static void print_mce_tail(void) 222static void print_mce_tail(void)
216{ 223{
217 printk(KERN_EMERG "This is not a software problem!\n" 224 printk(KERN_EMERG "This is not a software problem!\n"
218 "Run through mcelog --ascii to decode and contact your hardware vendor\n"); 225#if (!defined(CONFIG_EDAC) || !defined(CONFIG_CPU_SUP_AMD))
226 "Run through mcelog --ascii to decode and contact your hardware vendor\n"
227#endif
228 );
219} 229}
220 230
221#define PANIC_TIMEOUT 5 /* 5 seconds */ 231#define PANIC_TIMEOUT 5 /* 5 seconds */
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index ddae21620bda..1fecba404fd8 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -489,12 +489,14 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
489 int i, err = 0; 489 int i, err = 0;
490 struct threshold_bank *b = NULL; 490 struct threshold_bank *b = NULL;
491 char name[32]; 491 char name[32];
492 struct cpuinfo_x86 *c = &cpu_data(cpu);
493
492 494
493 sprintf(name, "threshold_bank%i", bank); 495 sprintf(name, "threshold_bank%i", bank);
494 496
495#ifdef CONFIG_SMP 497#ifdef CONFIG_SMP
496 if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */ 498 if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
497 i = cpumask_first(cpu_core_mask(cpu)); 499 i = cpumask_first(c->llc_shared_map);
498 500
499 /* first core not up yet */ 501 /* first core not up yet */
500 if (cpu_data(i).cpu_core_id) 502 if (cpu_data(i).cpu_core_id)
@@ -514,7 +516,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
514 if (err) 516 if (err)
515 goto out; 517 goto out;
516 518
517 cpumask_copy(b->cpus, cpu_core_mask(cpu)); 519 cpumask_copy(b->cpus, c->llc_shared_map);
518 per_cpu(threshold_banks, cpu)[bank] = b; 520 per_cpu(threshold_banks, cpu)[bank] = b;
519 521
520 goto out; 522 goto out;
@@ -539,7 +541,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
539#ifndef CONFIG_SMP 541#ifndef CONFIG_SMP
540 cpumask_setall(b->cpus); 542 cpumask_setall(b->cpus);
541#else 543#else
542 cpumask_copy(b->cpus, cpu_core_mask(cpu)); 544 cpumask_copy(b->cpus, c->llc_shared_map);
543#endif 545#endif
544 546
545 per_cpu(threshold_banks, cpu)[bank] = b; 547 per_cpu(threshold_banks, cpu)[bank] = b;
diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c
index ee2331b0e58f..33af14110dfd 100644
--- a/arch/x86/kernel/cpu/mtrr/amd.c
+++ b/arch/x86/kernel/cpu/mtrr/amd.c
@@ -7,15 +7,15 @@
7 7
8static void 8static void
9amd_get_mtrr(unsigned int reg, unsigned long *base, 9amd_get_mtrr(unsigned int reg, unsigned long *base,
10 unsigned long *size, mtrr_type * type) 10 unsigned long *size, mtrr_type *type)
11{ 11{
12 unsigned long low, high; 12 unsigned long low, high;
13 13
14 rdmsr(MSR_K6_UWCCR, low, high); 14 rdmsr(MSR_K6_UWCCR, low, high);
15 /* Upper dword is region 1, lower is region 0 */ 15 /* Upper dword is region 1, lower is region 0 */
16 if (reg == 1) 16 if (reg == 1)
17 low = high; 17 low = high;
18 /* The base masks off on the right alignment */ 18 /* The base masks off on the right alignment */
19 *base = (low & 0xFFFE0000) >> PAGE_SHIFT; 19 *base = (low & 0xFFFE0000) >> PAGE_SHIFT;
20 *type = 0; 20 *type = 0;
21 if (low & 1) 21 if (low & 1)
@@ -27,74 +27,81 @@ amd_get_mtrr(unsigned int reg, unsigned long *base,
27 return; 27 return;
28 } 28 }
29 /* 29 /*
30 * This needs a little explaining. The size is stored as an 30 * This needs a little explaining. The size is stored as an
31 * inverted mask of bits of 128K granularity 15 bits long offset 31 * inverted mask of bits of 128K granularity 15 bits long offset
32 * 2 bits 32 * 2 bits.
33 * 33 *
34 * So to get a size we do invert the mask and add 1 to the lowest 34 * So to get a size we do invert the mask and add 1 to the lowest
35 * mask bit (4 as its 2 bits in). This gives us a size we then shift 35 * mask bit (4 as its 2 bits in). This gives us a size we then shift
36 * to turn into 128K blocks 36 * to turn into 128K blocks.
37 * 37 *
38 * eg 111 1111 1111 1100 is 512K 38 * eg 111 1111 1111 1100 is 512K
39 * 39 *
40 * invert 000 0000 0000 0011 40 * invert 000 0000 0000 0011
41 * +1 000 0000 0000 0100 41 * +1 000 0000 0000 0100
42 * *128K ... 42 * *128K ...
43 */ 43 */
44 low = (~low) & 0x1FFFC; 44 low = (~low) & 0x1FFFC;
45 *size = (low + 4) << (15 - PAGE_SHIFT); 45 *size = (low + 4) << (15 - PAGE_SHIFT);
46 return;
47} 46}
48 47
49static void amd_set_mtrr(unsigned int reg, unsigned long base, 48/**
50 unsigned long size, mtrr_type type) 49 * amd_set_mtrr - Set variable MTRR register on the local CPU.
51/* [SUMMARY] Set variable MTRR register on the local CPU. 50 *
52 <reg> The register to set. 51 * @reg The register to set.
53 <base> The base address of the region. 52 * @base The base address of the region.
54 <size> The size of the region. If this is 0 the region is disabled. 53 * @size The size of the region. If this is 0 the region is disabled.
55 <type> The type of the region. 54 * @type The type of the region.
56 [RETURNS] Nothing. 55 *
57*/ 56 * Returns nothing.
57 */
58static void
59amd_set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
58{ 60{
59 u32 regs[2]; 61 u32 regs[2];
60 62
61 /* 63 /*
62 * Low is MTRR0 , High MTRR 1 64 * Low is MTRR0, High MTRR 1
63 */ 65 */
64 rdmsr(MSR_K6_UWCCR, regs[0], regs[1]); 66 rdmsr(MSR_K6_UWCCR, regs[0], regs[1]);
65 /* 67 /*
66 * Blank to disable 68 * Blank to disable
67 */ 69 */
68 if (size == 0) 70 if (size == 0) {
69 regs[reg] = 0; 71 regs[reg] = 0;
70 else 72 } else {
71 /* Set the register to the base, the type (off by one) and an 73 /*
72 inverted bitmask of the size The size is the only odd 74 * Set the register to the base, the type (off by one) and an
73 bit. We are fed say 512K We invert this and we get 111 1111 75 * inverted bitmask of the size The size is the only odd
74 1111 1011 but if you subtract one and invert you get the 76 * bit. We are fed say 512K We invert this and we get 111 1111
75 desired 111 1111 1111 1100 mask 77 * 1111 1011 but if you subtract one and invert you get the
76 78 * desired 111 1111 1111 1100 mask
77 But ~(x - 1) == ~x + 1 == -x. Two's complement rocks! */ 79 *
80 * But ~(x - 1) == ~x + 1 == -x. Two's complement rocks!
81 */
78 regs[reg] = (-size >> (15 - PAGE_SHIFT) & 0x0001FFFC) 82 regs[reg] = (-size >> (15 - PAGE_SHIFT) & 0x0001FFFC)
79 | (base << PAGE_SHIFT) | (type + 1); 83 | (base << PAGE_SHIFT) | (type + 1);
84 }
80 85
81 /* 86 /*
82 * The writeback rule is quite specific. See the manual. Its 87 * The writeback rule is quite specific. See the manual. Its
83 * disable local interrupts, write back the cache, set the mtrr 88 * disable local interrupts, write back the cache, set the mtrr
84 */ 89 */
85 wbinvd(); 90 wbinvd();
86 wrmsr(MSR_K6_UWCCR, regs[0], regs[1]); 91 wrmsr(MSR_K6_UWCCR, regs[0], regs[1]);
87} 92}
88 93
89static int amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type) 94static int
95amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
90{ 96{
91 /* Apply the K6 block alignment and size rules 97 /*
92 In order 98 * Apply the K6 block alignment and size rules
93 o Uncached or gathering only 99 * In order
94 o 128K or bigger block 100 * o Uncached or gathering only
95 o Power of 2 block 101 * o 128K or bigger block
96 o base suitably aligned to the power 102 * o Power of 2 block
97 */ 103 * o base suitably aligned to the power
104 */
98 if (type > MTRR_TYPE_WRCOMB || size < (1 << (17 - PAGE_SHIFT)) 105 if (type > MTRR_TYPE_WRCOMB || size < (1 << (17 - PAGE_SHIFT))
99 || (size & ~(size - 1)) - size || (base & (size - 1))) 106 || (size & ~(size - 1)) - size || (base & (size - 1)))
100 return -EINVAL; 107 return -EINVAL;
@@ -115,5 +122,3 @@ int __init amd_init_mtrr(void)
115 set_mtrr_ops(&amd_mtrr_ops); 122 set_mtrr_ops(&amd_mtrr_ops);
116 return 0; 123 return 0;
117} 124}
118
119//arch_initcall(amd_mtrr_init);
diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c
index cb9aa3a7a7ab..de89f14eff3a 100644
--- a/arch/x86/kernel/cpu/mtrr/centaur.c
+++ b/arch/x86/kernel/cpu/mtrr/centaur.c
@@ -1,7 +1,9 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/mm.h> 2#include <linux/mm.h>
3
3#include <asm/mtrr.h> 4#include <asm/mtrr.h>
4#include <asm/msr.h> 5#include <asm/msr.h>
6
5#include "mtrr.h" 7#include "mtrr.h"
6 8
7static struct { 9static struct {
@@ -12,25 +14,25 @@ static struct {
12static u8 centaur_mcr_reserved; 14static u8 centaur_mcr_reserved;
13static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ 15static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */
14 16
15/* 17/**
16 * Report boot time MCR setups 18 * centaur_get_free_region - Get a free MTRR.
19 *
20 * @base: The starting (base) address of the region.
21 * @size: The size (in bytes) of the region.
22 *
23 * Returns: the index of the region on success, else -1 on error.
17 */ 24 */
18
19static int 25static int
20centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) 26centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg)
21/* [SUMMARY] Get a free MTRR.
22 <base> The starting (base) address of the region.
23 <size> The size (in bytes) of the region.
24 [RETURNS] The index of the region on success, else -1 on error.
25*/
26{ 27{
27 int i, max;
28 mtrr_type ltype;
29 unsigned long lbase, lsize; 28 unsigned long lbase, lsize;
29 mtrr_type ltype;
30 int i, max;
30 31
31 max = num_var_ranges; 32 max = num_var_ranges;
32 if (replace_reg >= 0 && replace_reg < max) 33 if (replace_reg >= 0 && replace_reg < max)
33 return replace_reg; 34 return replace_reg;
35
34 for (i = 0; i < max; ++i) { 36 for (i = 0; i < max; ++i) {
35 if (centaur_mcr_reserved & (1 << i)) 37 if (centaur_mcr_reserved & (1 << i))
36 continue; 38 continue;
@@ -38,11 +40,14 @@ centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg)
38 if (lsize == 0) 40 if (lsize == 0)
39 return i; 41 return i;
40 } 42 }
43
41 return -ENOSPC; 44 return -ENOSPC;
42} 45}
43 46
44void 47/*
45mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) 48 * Report boot time MCR setups
49 */
50void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
46{ 51{
47 centaur_mcr[mcr].low = lo; 52 centaur_mcr[mcr].low = lo;
48 centaur_mcr[mcr].high = hi; 53 centaur_mcr[mcr].high = hi;
@@ -54,33 +59,35 @@ centaur_get_mcr(unsigned int reg, unsigned long *base,
54{ 59{
55 *base = centaur_mcr[reg].high >> PAGE_SHIFT; 60 *base = centaur_mcr[reg].high >> PAGE_SHIFT;
56 *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; 61 *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
57 *type = MTRR_TYPE_WRCOMB; /* If it is there, it is write-combining */ 62 *type = MTRR_TYPE_WRCOMB; /* write-combining */
63
58 if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2)) 64 if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2))
59 *type = MTRR_TYPE_UNCACHABLE; 65 *type = MTRR_TYPE_UNCACHABLE;
60 if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25) 66 if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25)
61 *type = MTRR_TYPE_WRBACK; 67 *type = MTRR_TYPE_WRBACK;
62 if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31) 68 if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31)
63 *type = MTRR_TYPE_WRBACK; 69 *type = MTRR_TYPE_WRBACK;
64
65} 70}
66 71
67static void centaur_set_mcr(unsigned int reg, unsigned long base, 72static void
68 unsigned long size, mtrr_type type) 73centaur_set_mcr(unsigned int reg, unsigned long base,
74 unsigned long size, mtrr_type type)
69{ 75{
70 unsigned long low, high; 76 unsigned long low, high;
71 77
72 if (size == 0) { 78 if (size == 0) {
73 /* Disable */ 79 /* Disable */
74 high = low = 0; 80 high = low = 0;
75 } else { 81 } else {
76 high = base << PAGE_SHIFT; 82 high = base << PAGE_SHIFT;
77 if (centaur_mcr_type == 0) 83 if (centaur_mcr_type == 0) {
78 low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */ 84 /* Only support write-combining... */
79 else { 85 low = -size << PAGE_SHIFT | 0x1f;
86 } else {
80 if (type == MTRR_TYPE_UNCACHABLE) 87 if (type == MTRR_TYPE_UNCACHABLE)
81 low = -size << PAGE_SHIFT | 0x02; /* NC */ 88 low = -size << PAGE_SHIFT | 0x02; /* NC */
82 else 89 else
83 low = -size << PAGE_SHIFT | 0x09; /* WWO,WC */ 90 low = -size << PAGE_SHIFT | 0x09; /* WWO, WC */
84 } 91 }
85 } 92 }
86 centaur_mcr[reg].high = high; 93 centaur_mcr[reg].high = high;
@@ -88,118 +95,16 @@ static void centaur_set_mcr(unsigned int reg, unsigned long base,
88 wrmsr(MSR_IDT_MCR0 + reg, low, high); 95 wrmsr(MSR_IDT_MCR0 + reg, low, high);
89} 96}
90 97
91#if 0 98static int
92/* 99centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
93 * Initialise the later (saner) Winchip MCR variant. In this version
94 * the BIOS can pass us the registers it has used (but not their values)
95 * and the control register is read/write
96 */
97
98static void __init
99centaur_mcr1_init(void)
100{
101 unsigned i;
102 u32 lo, hi;
103
104 /* Unfortunately, MCR's are read-only, so there is no way to
105 * find out what the bios might have done.
106 */
107
108 rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
109 if (((lo >> 17) & 7) == 1) { /* Type 1 Winchip2 MCR */
110 lo &= ~0x1C0; /* clear key */
111 lo |= 0x040; /* set key to 1 */
112 wrmsr(MSR_IDT_MCR_CTRL, lo, hi); /* unlock MCR */
113 }
114
115 centaur_mcr_type = 1;
116
117 /*
118 * Clear any unconfigured MCR's.
119 */
120
121 for (i = 0; i < 8; ++i) {
122 if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) {
123 if (!(lo & (1 << (9 + i))))
124 wrmsr(MSR_IDT_MCR0 + i, 0, 0);
125 else
126 /*
127 * If the BIOS set up an MCR we cannot see it
128 * but we don't wish to obliterate it
129 */
130 centaur_mcr_reserved |= (1 << i);
131 }
132 }
133 /*
134 * Throw the main write-combining switch...
135 * However if OOSTORE is enabled then people have already done far
136 * cleverer things and we should behave.
137 */
138
139 lo |= 15; /* Write combine enables */
140 wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
141}
142
143/*
144 * Initialise the original winchip with read only MCR registers
145 * no used bitmask for the BIOS to pass on and write only control
146 */
147
148static void __init
149centaur_mcr0_init(void)
150{
151 unsigned i;
152
153 /* Unfortunately, MCR's are read-only, so there is no way to
154 * find out what the bios might have done.
155 */
156
157 /* Clear any unconfigured MCR's.
158 * This way we are sure that the centaur_mcr array contains the actual
159 * values. The disadvantage is that any BIOS tweaks are thus undone.
160 *
161 */
162 for (i = 0; i < 8; ++i) {
163 if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0)
164 wrmsr(MSR_IDT_MCR0 + i, 0, 0);
165 }
166
167 wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); /* Write only */
168}
169
170/*
171 * Initialise Winchip series MCR registers
172 */
173
174static void __init
175centaur_mcr_init(void)
176{
177 struct set_mtrr_context ctxt;
178
179 set_mtrr_prepare_save(&ctxt);
180 set_mtrr_cache_disable(&ctxt);
181
182 if (boot_cpu_data.x86_model == 4)
183 centaur_mcr0_init();
184 else if (boot_cpu_data.x86_model == 8 || boot_cpu_data.x86_model == 9)
185 centaur_mcr1_init();
186
187 set_mtrr_done(&ctxt);
188}
189#endif
190
191static int centaur_validate_add_page(unsigned long base,
192 unsigned long size, unsigned int type)
193{ 100{
194 /* 101 /*
195 * FIXME: Winchip2 supports uncached 102 * FIXME: Winchip2 supports uncached
196 */ 103 */
197 if (type != MTRR_TYPE_WRCOMB && 104 if (type != MTRR_TYPE_WRCOMB &&
198 (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) { 105 (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) {
199 printk(KERN_WARNING 106 pr_warning("mtrr: only write-combining%s supported\n",
200 "mtrr: only write-combining%s supported\n", 107 centaur_mcr_type ? " and uncacheable are" : " is");
201 centaur_mcr_type ? " and uncacheable are"
202 : " is");
203 return -EINVAL; 108 return -EINVAL;
204 } 109 }
205 return 0; 110 return 0;
@@ -207,7 +112,6 @@ static int centaur_validate_add_page(unsigned long base,
207 112
208static struct mtrr_ops centaur_mtrr_ops = { 113static struct mtrr_ops centaur_mtrr_ops = {
209 .vendor = X86_VENDOR_CENTAUR, 114 .vendor = X86_VENDOR_CENTAUR,
210// .init = centaur_mcr_init,
211 .set = centaur_set_mcr, 115 .set = centaur_set_mcr,
212 .get = centaur_get_mcr, 116 .get = centaur_get_mcr,
213 .get_free_region = centaur_get_free_region, 117 .get_free_region = centaur_get_free_region,
@@ -220,5 +124,3 @@ int __init centaur_init_mtrr(void)
220 set_mtrr_ops(&centaur_mtrr_ops); 124 set_mtrr_ops(&centaur_mtrr_ops);
221 return 0; 125 return 0;
222} 126}
223
224//arch_initcall(centaur_init_mtrr);
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 1d584a18a50d..315738c74aad 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -1,51 +1,75 @@
1/* MTRR (Memory Type Range Register) cleanup 1/*
2 2 * MTRR (Memory Type Range Register) cleanup
3 Copyright (C) 2009 Yinghai Lu 3 *
4 4 * Copyright (C) 2009 Yinghai Lu
5 This library is free software; you can redistribute it and/or 5 *
6 modify it under the terms of the GNU Library General Public 6 * This library is free software; you can redistribute it and/or
7 License as published by the Free Software Foundation; either 7 * modify it under the terms of the GNU Library General Public
8 version 2 of the License, or (at your option) any later version. 8 * License as published by the Free Software Foundation; either
9 9 * version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful, 10 *
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * This library is distributed in the hope that it will be useful,
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 Library General Public License for more details. 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 14 * Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public 15 *
16 License along with this library; if not, write to the Free 16 * You should have received a copy of the GNU Library General Public
17 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 * License along with this library; if not, write to the Free
18*/ 18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 19 */
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/smp.h> 23#include <linux/smp.h>
24#include <linux/cpu.h> 24#include <linux/cpu.h>
25#include <linux/mutex.h>
26#include <linux/sort.h> 25#include <linux/sort.h>
26#include <linux/mutex.h>
27#include <linux/uaccess.h>
28#include <linux/kvm_para.h>
27 29
30#include <asm/processor.h>
28#include <asm/e820.h> 31#include <asm/e820.h>
29#include <asm/mtrr.h> 32#include <asm/mtrr.h>
30#include <asm/uaccess.h>
31#include <asm/processor.h>
32#include <asm/msr.h> 33#include <asm/msr.h>
33#include <asm/kvm_para.h>
34#include "mtrr.h"
35 34
36/* should be related to MTRR_VAR_RANGES nums */ 35#include "mtrr.h"
37#define RANGE_NUM 256
38 36
39struct res_range { 37struct res_range {
40 unsigned long start; 38 unsigned long start;
41 unsigned long end; 39 unsigned long end;
40};
41
42struct var_mtrr_range_state {
43 unsigned long base_pfn;
44 unsigned long size_pfn;
45 mtrr_type type;
46};
47
48struct var_mtrr_state {
49 unsigned long range_startk;
50 unsigned long range_sizek;
51 unsigned long chunk_sizek;
52 unsigned long gran_sizek;
53 unsigned int reg;
42}; 54};
43 55
56/* Should be related to MTRR_VAR_RANGES nums */
57#define RANGE_NUM 256
58
59static struct res_range __initdata range[RANGE_NUM];
60static int __initdata nr_range;
61
62static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
63
64static int __initdata debug_print;
65#define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0)
66
67
44static int __init 68static int __init
45add_range(struct res_range *range, int nr_range, unsigned long start, 69add_range(struct res_range *range, int nr_range,
46 unsigned long end) 70 unsigned long start, unsigned long end)
47{ 71{
48 /* out of slots */ 72 /* Out of slots: */
49 if (nr_range >= RANGE_NUM) 73 if (nr_range >= RANGE_NUM)
50 return nr_range; 74 return nr_range;
51 75
@@ -58,12 +82,12 @@ add_range(struct res_range *range, int nr_range, unsigned long start,
58} 82}
59 83
60static int __init 84static int __init
61add_range_with_merge(struct res_range *range, int nr_range, unsigned long start, 85add_range_with_merge(struct res_range *range, int nr_range,
62 unsigned long end) 86 unsigned long start, unsigned long end)
63{ 87{
64 int i; 88 int i;
65 89
66 /* try to merge it with old one */ 90 /* Try to merge it with old one: */
67 for (i = 0; i < nr_range; i++) { 91 for (i = 0; i < nr_range; i++) {
68 unsigned long final_start, final_end; 92 unsigned long final_start, final_end;
69 unsigned long common_start, common_end; 93 unsigned long common_start, common_end;
@@ -84,7 +108,7 @@ add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
84 return nr_range; 108 return nr_range;
85 } 109 }
86 110
87 /* need to add that */ 111 /* Need to add it: */
88 return add_range(range, nr_range, start, end); 112 return add_range(range, nr_range, start, end);
89} 113}
90 114
@@ -117,7 +141,7 @@ subtract_range(struct res_range *range, unsigned long start, unsigned long end)
117 } 141 }
118 142
119 if (start > range[j].start && end < range[j].end) { 143 if (start > range[j].start && end < range[j].end) {
120 /* find the new spare */ 144 /* Find the new spare: */
121 for (i = 0; i < RANGE_NUM; i++) { 145 for (i = 0; i < RANGE_NUM; i++) {
122 if (range[i].end == 0) 146 if (range[i].end == 0)
123 break; 147 break;
@@ -146,14 +170,8 @@ static int __init cmp_range(const void *x1, const void *x2)
146 return start1 - start2; 170 return start1 - start2;
147} 171}
148 172
149struct var_mtrr_range_state { 173#define BIOS_BUG_MSG KERN_WARNING \
150 unsigned long base_pfn; 174 "WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
151 unsigned long size_pfn;
152 mtrr_type type;
153};
154
155static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
156static int __initdata debug_print;
157 175
158static int __init 176static int __init
159x86_get_mtrr_mem_range(struct res_range *range, int nr_range, 177x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
@@ -180,7 +198,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
180 range[i].start, range[i].end + 1); 198 range[i].start, range[i].end + 1);
181 } 199 }
182 200
183 /* take out UC ranges */ 201 /* Take out UC ranges: */
184 for (i = 0; i < num_var_ranges; i++) { 202 for (i = 0; i < num_var_ranges; i++) {
185 type = range_state[i].type; 203 type = range_state[i].type;
186 if (type != MTRR_TYPE_UNCACHABLE && 204 if (type != MTRR_TYPE_UNCACHABLE &&
@@ -193,9 +211,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
193 if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed && 211 if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
194 (mtrr_state.enabled & 1)) { 212 (mtrr_state.enabled & 1)) {
195 /* Var MTRR contains UC entry below 1M? Skip it: */ 213 /* Var MTRR contains UC entry below 1M? Skip it: */
196 printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d " 214 printk(BIOS_BUG_MSG, i);
197 "contains strange UC entry under 1M, check "
198 "with your system vendor!\n", i);
199 if (base + size <= (1<<(20-PAGE_SHIFT))) 215 if (base + size <= (1<<(20-PAGE_SHIFT)))
200 continue; 216 continue;
201 size -= (1<<(20-PAGE_SHIFT)) - base; 217 size -= (1<<(20-PAGE_SHIFT)) - base;
@@ -237,17 +253,13 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
237 return nr_range; 253 return nr_range;
238} 254}
239 255
240static struct res_range __initdata range[RANGE_NUM];
241static int __initdata nr_range;
242
243#ifdef CONFIG_MTRR_SANITIZER 256#ifdef CONFIG_MTRR_SANITIZER
244 257
245static unsigned long __init sum_ranges(struct res_range *range, int nr_range) 258static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
246{ 259{
247 unsigned long sum; 260 unsigned long sum = 0;
248 int i; 261 int i;
249 262
250 sum = 0;
251 for (i = 0; i < nr_range; i++) 263 for (i = 0; i < nr_range; i++)
252 sum += range[i].end + 1 - range[i].start; 264 sum += range[i].end + 1 - range[i].start;
253 265
@@ -278,17 +290,9 @@ static int __init mtrr_cleanup_debug_setup(char *str)
278} 290}
279early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup); 291early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
280 292
281struct var_mtrr_state {
282 unsigned long range_startk;
283 unsigned long range_sizek;
284 unsigned long chunk_sizek;
285 unsigned long gran_sizek;
286 unsigned int reg;
287};
288
289static void __init 293static void __init
290set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, 294set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
291 unsigned char type, unsigned int address_bits) 295 unsigned char type, unsigned int address_bits)
292{ 296{
293 u32 base_lo, base_hi, mask_lo, mask_hi; 297 u32 base_lo, base_hi, mask_lo, mask_hi;
294 u64 base, mask; 298 u64 base, mask;
@@ -301,7 +305,7 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
301 mask = (1ULL << address_bits) - 1; 305 mask = (1ULL << address_bits) - 1;
302 mask &= ~((((u64)sizek) << 10) - 1); 306 mask &= ~((((u64)sizek) << 10) - 1);
303 307
304 base = ((u64)basek) << 10; 308 base = ((u64)basek) << 10;
305 309
306 base |= type; 310 base |= type;
307 mask |= 0x800; 311 mask |= 0x800;
@@ -317,15 +321,14 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
317 321
318static void __init 322static void __init
319save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, 323save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
320 unsigned char type) 324 unsigned char type)
321{ 325{
322 range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10); 326 range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10);
323 range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10); 327 range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10);
324 range_state[reg].type = type; 328 range_state[reg].type = type;
325} 329}
326 330
327static void __init 331static void __init set_var_mtrr_all(unsigned int address_bits)
328set_var_mtrr_all(unsigned int address_bits)
329{ 332{
330 unsigned long basek, sizek; 333 unsigned long basek, sizek;
331 unsigned char type; 334 unsigned char type;
@@ -342,11 +345,11 @@ set_var_mtrr_all(unsigned int address_bits)
342 345
343static unsigned long to_size_factor(unsigned long sizek, char *factorp) 346static unsigned long to_size_factor(unsigned long sizek, char *factorp)
344{ 347{
345 char factor;
346 unsigned long base = sizek; 348 unsigned long base = sizek;
349 char factor;
347 350
348 if (base & ((1<<10) - 1)) { 351 if (base & ((1<<10) - 1)) {
349 /* not MB alignment */ 352 /* Not MB-aligned: */
350 factor = 'K'; 353 factor = 'K';
351 } else if (base & ((1<<20) - 1)) { 354 } else if (base & ((1<<20) - 1)) {
352 factor = 'M'; 355 factor = 'M';
@@ -372,11 +375,12 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
372 unsigned long max_align, align; 375 unsigned long max_align, align;
373 unsigned long sizek; 376 unsigned long sizek;
374 377
375 /* Compute the maximum size I can make a range */ 378 /* Compute the maximum size with which we can make a range: */
376 if (range_startk) 379 if (range_startk)
377 max_align = ffs(range_startk) - 1; 380 max_align = ffs(range_startk) - 1;
378 else 381 else
379 max_align = 32; 382 max_align = 32;
383
380 align = fls(range_sizek) - 1; 384 align = fls(range_sizek) - 1;
381 if (align > max_align) 385 if (align > max_align)
382 align = max_align; 386 align = max_align;
@@ -386,11 +390,10 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
386 char start_factor = 'K', size_factor = 'K'; 390 char start_factor = 'K', size_factor = 'K';
387 unsigned long start_base, size_base; 391 unsigned long start_base, size_base;
388 392
389 start_base = to_size_factor(range_startk, 393 start_base = to_size_factor(range_startk, &start_factor);
390 &start_factor), 394 size_base = to_size_factor(sizek, &size_factor);
391 size_base = to_size_factor(sizek, &size_factor),
392 395
393 printk(KERN_DEBUG "Setting variable MTRR %d, " 396 Dprintk("Setting variable MTRR %d, "
394 "base: %ld%cB, range: %ld%cB, type %s\n", 397 "base: %ld%cB, range: %ld%cB, type %s\n",
395 reg, start_base, start_factor, 398 reg, start_base, start_factor,
396 size_base, size_factor, 399 size_base, size_factor,
@@ -425,10 +428,11 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
425 chunk_sizek = state->chunk_sizek; 428 chunk_sizek = state->chunk_sizek;
426 gran_sizek = state->gran_sizek; 429 gran_sizek = state->gran_sizek;
427 430
428 /* align with gran size, prevent small block used up MTRRs */ 431 /* Align with gran size, prevent small block used up MTRRs: */
429 range_basek = ALIGN(state->range_startk, gran_sizek); 432 range_basek = ALIGN(state->range_startk, gran_sizek);
430 if ((range_basek > basek) && basek) 433 if ((range_basek > basek) && basek)
431 return second_sizek; 434 return second_sizek;
435
432 state->range_sizek -= (range_basek - state->range_startk); 436 state->range_sizek -= (range_basek - state->range_startk);
433 range_sizek = ALIGN(state->range_sizek, gran_sizek); 437 range_sizek = ALIGN(state->range_sizek, gran_sizek);
434 438
@@ -439,22 +443,21 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
439 } 443 }
440 state->range_sizek = range_sizek; 444 state->range_sizek = range_sizek;
441 445
442 /* try to append some small hole */ 446 /* Try to append some small hole: */
443 range0_basek = state->range_startk; 447 range0_basek = state->range_startk;
444 range0_sizek = ALIGN(state->range_sizek, chunk_sizek); 448 range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
445 449
446 /* no increase */ 450 /* No increase: */
447 if (range0_sizek == state->range_sizek) { 451 if (range0_sizek == state->range_sizek) {
448 if (debug_print) 452 Dprintk("rangeX: %016lx - %016lx\n",
449 printk(KERN_DEBUG "rangeX: %016lx - %016lx\n", 453 range0_basek<<10,
450 range0_basek<<10, 454 (range0_basek + state->range_sizek)<<10);
451 (range0_basek + state->range_sizek)<<10);
452 state->reg = range_to_mtrr(state->reg, range0_basek, 455 state->reg = range_to_mtrr(state->reg, range0_basek,
453 state->range_sizek, MTRR_TYPE_WRBACK); 456 state->range_sizek, MTRR_TYPE_WRBACK);
454 return 0; 457 return 0;
455 } 458 }
456 459
457 /* only cut back, when it is not the last */ 460 /* Only cut back when it is not the last: */
458 if (sizek) { 461 if (sizek) {
459 while (range0_basek + range0_sizek > (basek + sizek)) { 462 while (range0_basek + range0_sizek > (basek + sizek)) {
460 if (range0_sizek >= chunk_sizek) 463 if (range0_sizek >= chunk_sizek)
@@ -470,16 +473,16 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
470second_try: 473second_try:
471 range_basek = range0_basek + range0_sizek; 474 range_basek = range0_basek + range0_sizek;
472 475
473 /* one hole in the middle */ 476 /* One hole in the middle: */
474 if (range_basek > basek && range_basek <= (basek + sizek)) 477 if (range_basek > basek && range_basek <= (basek + sizek))
475 second_sizek = range_basek - basek; 478 second_sizek = range_basek - basek;
476 479
477 if (range0_sizek > state->range_sizek) { 480 if (range0_sizek > state->range_sizek) {
478 481
479 /* one hole in middle or at end */ 482 /* One hole in middle or at the end: */
480 hole_sizek = range0_sizek - state->range_sizek - second_sizek; 483 hole_sizek = range0_sizek - state->range_sizek - second_sizek;
481 484
482 /* hole size should be less than half of range0 size */ 485 /* Hole size should be less than half of range0 size: */
483 if (hole_sizek >= (range0_sizek >> 1) && 486 if (hole_sizek >= (range0_sizek >> 1) &&
484 range0_sizek >= chunk_sizek) { 487 range0_sizek >= chunk_sizek) {
485 range0_sizek -= chunk_sizek; 488 range0_sizek -= chunk_sizek;
@@ -491,32 +494,30 @@ second_try:
491 } 494 }
492 495
493 if (range0_sizek) { 496 if (range0_sizek) {
494 if (debug_print) 497 Dprintk("range0: %016lx - %016lx\n",
495 printk(KERN_DEBUG "range0: %016lx - %016lx\n", 498 range0_basek<<10,
496 range0_basek<<10, 499 (range0_basek + range0_sizek)<<10);
497 (range0_basek + range0_sizek)<<10);
498 state->reg = range_to_mtrr(state->reg, range0_basek, 500 state->reg = range_to_mtrr(state->reg, range0_basek,
499 range0_sizek, MTRR_TYPE_WRBACK); 501 range0_sizek, MTRR_TYPE_WRBACK);
500 } 502 }
501 503
502 if (range0_sizek < state->range_sizek) { 504 if (range0_sizek < state->range_sizek) {
503 /* need to handle left over */ 505 /* Need to handle left over range: */
504 range_sizek = state->range_sizek - range0_sizek; 506 range_sizek = state->range_sizek - range0_sizek;
505 507
506 if (debug_print) 508 Dprintk("range: %016lx - %016lx\n",
507 printk(KERN_DEBUG "range: %016lx - %016lx\n", 509 range_basek<<10,
508 range_basek<<10, 510 (range_basek + range_sizek)<<10);
509 (range_basek + range_sizek)<<10); 511
510 state->reg = range_to_mtrr(state->reg, range_basek, 512 state->reg = range_to_mtrr(state->reg, range_basek,
511 range_sizek, MTRR_TYPE_WRBACK); 513 range_sizek, MTRR_TYPE_WRBACK);
512 } 514 }
513 515
514 if (hole_sizek) { 516 if (hole_sizek) {
515 hole_basek = range_basek - hole_sizek - second_sizek; 517 hole_basek = range_basek - hole_sizek - second_sizek;
516 if (debug_print) 518 Dprintk("hole: %016lx - %016lx\n",
517 printk(KERN_DEBUG "hole: %016lx - %016lx\n", 519 hole_basek<<10,
518 hole_basek<<10, 520 (hole_basek + hole_sizek)<<10);
519 (hole_basek + hole_sizek)<<10);
520 state->reg = range_to_mtrr(state->reg, hole_basek, 521 state->reg = range_to_mtrr(state->reg, hole_basek,
521 hole_sizek, MTRR_TYPE_UNCACHABLE); 522 hole_sizek, MTRR_TYPE_UNCACHABLE);
522 } 523 }
@@ -537,23 +538,23 @@ set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
537 basek = base_pfn << (PAGE_SHIFT - 10); 538 basek = base_pfn << (PAGE_SHIFT - 10);
538 sizek = size_pfn << (PAGE_SHIFT - 10); 539 sizek = size_pfn << (PAGE_SHIFT - 10);
539 540
540 /* See if I can merge with the last range */ 541 /* See if I can merge with the last range: */
541 if ((basek <= 1024) || 542 if ((basek <= 1024) ||
542 (state->range_startk + state->range_sizek == basek)) { 543 (state->range_startk + state->range_sizek == basek)) {
543 unsigned long endk = basek + sizek; 544 unsigned long endk = basek + sizek;
544 state->range_sizek = endk - state->range_startk; 545 state->range_sizek = endk - state->range_startk;
545 return; 546 return;
546 } 547 }
547 /* Write the range mtrrs */ 548 /* Write the range mtrrs: */
548 if (state->range_sizek != 0) 549 if (state->range_sizek != 0)
549 second_sizek = range_to_mtrr_with_hole(state, basek, sizek); 550 second_sizek = range_to_mtrr_with_hole(state, basek, sizek);
550 551
551 /* Allocate an msr */ 552 /* Allocate an msr: */
552 state->range_startk = basek + second_sizek; 553 state->range_startk = basek + second_sizek;
553 state->range_sizek = sizek - second_sizek; 554 state->range_sizek = sizek - second_sizek;
554} 555}
555 556
556/* mininum size of mtrr block that can take hole */ 557/* Mininum size of mtrr block that can take hole: */
557static u64 mtrr_chunk_size __initdata = (256ULL<<20); 558static u64 mtrr_chunk_size __initdata = (256ULL<<20);
558 559
559static int __init parse_mtrr_chunk_size_opt(char *p) 560static int __init parse_mtrr_chunk_size_opt(char *p)
@@ -565,7 +566,7 @@ static int __init parse_mtrr_chunk_size_opt(char *p)
565} 566}
566early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt); 567early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
567 568
568/* granity of mtrr of block */ 569/* Granularity of mtrr of block: */
569static u64 mtrr_gran_size __initdata; 570static u64 mtrr_gran_size __initdata;
570 571
571static int __init parse_mtrr_gran_size_opt(char *p) 572static int __init parse_mtrr_gran_size_opt(char *p)
@@ -577,7 +578,7 @@ static int __init parse_mtrr_gran_size_opt(char *p)
577} 578}
578early_param("mtrr_gran_size", parse_mtrr_gran_size_opt); 579early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
579 580
580static int nr_mtrr_spare_reg __initdata = 581static unsigned long nr_mtrr_spare_reg __initdata =
581 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT; 582 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT;
582 583
583static int __init parse_mtrr_spare_reg(char *arg) 584static int __init parse_mtrr_spare_reg(char *arg)
@@ -586,7 +587,6 @@ static int __init parse_mtrr_spare_reg(char *arg)
586 nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0); 587 nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0);
587 return 0; 588 return 0;
588} 589}
589
590early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg); 590early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
591 591
592static int __init 592static int __init
@@ -594,8 +594,8 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range,
594 u64 chunk_size, u64 gran_size) 594 u64 chunk_size, u64 gran_size)
595{ 595{
596 struct var_mtrr_state var_state; 596 struct var_mtrr_state var_state;
597 int i;
598 int num_reg; 597 int num_reg;
598 int i;
599 599
600 var_state.range_startk = 0; 600 var_state.range_startk = 0;
601 var_state.range_sizek = 0; 601 var_state.range_sizek = 0;
@@ -605,17 +605,18 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range,
605 605
606 memset(range_state, 0, sizeof(range_state)); 606 memset(range_state, 0, sizeof(range_state));
607 607
608 /* Write the range etc */ 608 /* Write the range: */
609 for (i = 0; i < nr_range; i++) 609 for (i = 0; i < nr_range; i++) {
610 set_var_mtrr_range(&var_state, range[i].start, 610 set_var_mtrr_range(&var_state, range[i].start,
611 range[i].end - range[i].start + 1); 611 range[i].end - range[i].start + 1);
612 }
612 613
613 /* Write the last range */ 614 /* Write the last range: */
614 if (var_state.range_sizek != 0) 615 if (var_state.range_sizek != 0)
615 range_to_mtrr_with_hole(&var_state, 0, 0); 616 range_to_mtrr_with_hole(&var_state, 0, 0);
616 617
617 num_reg = var_state.reg; 618 num_reg = var_state.reg;
618 /* Clear out the extra MTRR's */ 619 /* Clear out the extra MTRR's: */
619 while (var_state.reg < num_var_ranges) { 620 while (var_state.reg < num_var_ranges) {
620 save_var_mtrr(var_state.reg, 0, 0, 0); 621 save_var_mtrr(var_state.reg, 0, 0, 0);
621 var_state.reg++; 622 var_state.reg++;
@@ -625,11 +626,11 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range,
625} 626}
626 627
627struct mtrr_cleanup_result { 628struct mtrr_cleanup_result {
628 unsigned long gran_sizek; 629 unsigned long gran_sizek;
629 unsigned long chunk_sizek; 630 unsigned long chunk_sizek;
630 unsigned long lose_cover_sizek; 631 unsigned long lose_cover_sizek;
631 unsigned int num_reg; 632 unsigned int num_reg;
632 int bad; 633 int bad;
633}; 634};
634 635
635/* 636/*
@@ -645,10 +646,10 @@ static unsigned long __initdata min_loss_pfn[RANGE_NUM];
645 646
646static void __init print_out_mtrr_range_state(void) 647static void __init print_out_mtrr_range_state(void)
647{ 648{
648 int i;
649 char start_factor = 'K', size_factor = 'K'; 649 char start_factor = 'K', size_factor = 'K';
650 unsigned long start_base, size_base; 650 unsigned long start_base, size_base;
651 mtrr_type type; 651 mtrr_type type;
652 int i;
652 653
653 for (i = 0; i < num_var_ranges; i++) { 654 for (i = 0; i < num_var_ranges; i++) {
654 655
@@ -676,10 +677,10 @@ static int __init mtrr_need_cleanup(void)
676 int i; 677 int i;
677 mtrr_type type; 678 mtrr_type type;
678 unsigned long size; 679 unsigned long size;
679 /* extra one for all 0 */ 680 /* Extra one for all 0: */
680 int num[MTRR_NUM_TYPES + 1]; 681 int num[MTRR_NUM_TYPES + 1];
681 682
682 /* check entries number */ 683 /* Check entries number: */
683 memset(num, 0, sizeof(num)); 684 memset(num, 0, sizeof(num));
684 for (i = 0; i < num_var_ranges; i++) { 685 for (i = 0; i < num_var_ranges; i++) {
685 type = range_state[i].type; 686 type = range_state[i].type;
@@ -693,88 +694,86 @@ static int __init mtrr_need_cleanup(void)
693 num[type]++; 694 num[type]++;
694 } 695 }
695 696
696 /* check if we got UC entries */ 697 /* Check if we got UC entries: */
697 if (!num[MTRR_TYPE_UNCACHABLE]) 698 if (!num[MTRR_TYPE_UNCACHABLE])
698 return 0; 699 return 0;
699 700
700 /* check if we only had WB and UC */ 701 /* Check if we only had WB and UC */
701 if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != 702 if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
702 num_var_ranges - num[MTRR_NUM_TYPES]) 703 num_var_ranges - num[MTRR_NUM_TYPES])
703 return 0; 704 return 0;
704 705
705 return 1; 706 return 1;
706} 707}
707 708
708static unsigned long __initdata range_sums; 709static unsigned long __initdata range_sums;
709static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size, 710
710 unsigned long extra_remove_base, 711static void __init
711 unsigned long extra_remove_size, 712mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
712 int i) 713 unsigned long x_remove_base,
714 unsigned long x_remove_size, int i)
713{ 715{
714 int num_reg;
715 static struct res_range range_new[RANGE_NUM]; 716 static struct res_range range_new[RANGE_NUM];
716 static int nr_range_new;
717 unsigned long range_sums_new; 717 unsigned long range_sums_new;
718 static int nr_range_new;
719 int num_reg;
718 720
719 /* convert ranges to var ranges state */ 721 /* Convert ranges to var ranges state: */
720 num_reg = x86_setup_var_mtrrs(range, nr_range, 722 num_reg = x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
721 chunk_size, gran_size);
722 723
723 /* we got new setting in range_state, check it */ 724 /* We got new setting in range_state, check it: */
724 memset(range_new, 0, sizeof(range_new)); 725 memset(range_new, 0, sizeof(range_new));
725 nr_range_new = x86_get_mtrr_mem_range(range_new, 0, 726 nr_range_new = x86_get_mtrr_mem_range(range_new, 0,
726 extra_remove_base, extra_remove_size); 727 x_remove_base, x_remove_size);
727 range_sums_new = sum_ranges(range_new, nr_range_new); 728 range_sums_new = sum_ranges(range_new, nr_range_new);
728 729
729 result[i].chunk_sizek = chunk_size >> 10; 730 result[i].chunk_sizek = chunk_size >> 10;
730 result[i].gran_sizek = gran_size >> 10; 731 result[i].gran_sizek = gran_size >> 10;
731 result[i].num_reg = num_reg; 732 result[i].num_reg = num_reg;
733
732 if (range_sums < range_sums_new) { 734 if (range_sums < range_sums_new) {
733 result[i].lose_cover_sizek = 735 result[i].lose_cover_sizek = (range_sums_new - range_sums) << PSHIFT;
734 (range_sums_new - range_sums) << PSHIFT;
735 result[i].bad = 1; 736 result[i].bad = 1;
736 } else 737 } else {
737 result[i].lose_cover_sizek = 738 result[i].lose_cover_sizek = (range_sums - range_sums_new) << PSHIFT;
738 (range_sums - range_sums_new) << PSHIFT; 739 }
739 740
740 /* double check it */ 741 /* Double check it: */
741 if (!result[i].bad && !result[i].lose_cover_sizek) { 742 if (!result[i].bad && !result[i].lose_cover_sizek) {
742 if (nr_range_new != nr_range || 743 if (nr_range_new != nr_range || memcmp(range, range_new, sizeof(range)))
743 memcmp(range, range_new, sizeof(range))) 744 result[i].bad = 1;
744 result[i].bad = 1;
745 } 745 }
746 746
747 if (!result[i].bad && (range_sums - range_sums_new < 747 if (!result[i].bad && (range_sums - range_sums_new < min_loss_pfn[num_reg]))
748 min_loss_pfn[num_reg])) { 748 min_loss_pfn[num_reg] = range_sums - range_sums_new;
749 min_loss_pfn[num_reg] =
750 range_sums - range_sums_new;
751 }
752} 749}
753 750
754static void __init mtrr_print_out_one_result(int i) 751static void __init mtrr_print_out_one_result(int i)
755{ 752{
756 char gran_factor, chunk_factor, lose_factor;
757 unsigned long gran_base, chunk_base, lose_base; 753 unsigned long gran_base, chunk_base, lose_base;
754 char gran_factor, chunk_factor, lose_factor;
758 755
759 gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), 756 gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
760 chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), 757 chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
761 lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), 758 lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
762 printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t", 759
763 result[i].bad ? "*BAD*" : " ", 760 pr_info("%sgran_size: %ld%c \tchunk_size: %ld%c \t",
764 gran_base, gran_factor, chunk_base, chunk_factor); 761 result[i].bad ? "*BAD*" : " ",
765 printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n", 762 gran_base, gran_factor, chunk_base, chunk_factor);
766 result[i].num_reg, result[i].bad ? "-" : "", 763 pr_cont("num_reg: %d \tlose cover RAM: %s%ld%c\n",
767 lose_base, lose_factor); 764 result[i].num_reg, result[i].bad ? "-" : "",
765 lose_base, lose_factor);
768} 766}
769 767
770static int __init mtrr_search_optimal_index(void) 768static int __init mtrr_search_optimal_index(void)
771{ 769{
772 int i;
773 int num_reg_good; 770 int num_reg_good;
774 int index_good; 771 int index_good;
772 int i;
775 773
776 if (nr_mtrr_spare_reg >= num_var_ranges) 774 if (nr_mtrr_spare_reg >= num_var_ranges)
777 nr_mtrr_spare_reg = num_var_ranges - 1; 775 nr_mtrr_spare_reg = num_var_ranges - 1;
776
778 num_reg_good = -1; 777 num_reg_good = -1;
779 for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) { 778 for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
780 if (!min_loss_pfn[i]) 779 if (!min_loss_pfn[i])
@@ -796,24 +795,24 @@ static int __init mtrr_search_optimal_index(void)
796 return index_good; 795 return index_good;
797} 796}
798 797
799
800int __init mtrr_cleanup(unsigned address_bits) 798int __init mtrr_cleanup(unsigned address_bits)
801{ 799{
802 unsigned long extra_remove_base, extra_remove_size; 800 unsigned long x_remove_base, x_remove_size;
803 unsigned long base, size, def, dummy; 801 unsigned long base, size, def, dummy;
804 mtrr_type type;
805 u64 chunk_size, gran_size; 802 u64 chunk_size, gran_size;
803 mtrr_type type;
806 int index_good; 804 int index_good;
807 int i; 805 int i;
808 806
809 if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1) 807 if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
810 return 0; 808 return 0;
809
811 rdmsr(MSR_MTRRdefType, def, dummy); 810 rdmsr(MSR_MTRRdefType, def, dummy);
812 def &= 0xff; 811 def &= 0xff;
813 if (def != MTRR_TYPE_UNCACHABLE) 812 if (def != MTRR_TYPE_UNCACHABLE)
814 return 0; 813 return 0;
815 814
816 /* get it and store it aside */ 815 /* Get it and store it aside: */
817 memset(range_state, 0, sizeof(range_state)); 816 memset(range_state, 0, sizeof(range_state));
818 for (i = 0; i < num_var_ranges; i++) { 817 for (i = 0; i < num_var_ranges; i++) {
819 mtrr_if->get(i, &base, &size, &type); 818 mtrr_if->get(i, &base, &size, &type);
@@ -822,29 +821,28 @@ int __init mtrr_cleanup(unsigned address_bits)
822 range_state[i].type = type; 821 range_state[i].type = type;
823 } 822 }
824 823
825 /* check if we need handle it and can handle it */ 824 /* Check if we need handle it and can handle it: */
826 if (!mtrr_need_cleanup()) 825 if (!mtrr_need_cleanup())
827 return 0; 826 return 0;
828 827
829 /* print original var MTRRs at first, for debugging: */ 828 /* Print original var MTRRs at first, for debugging: */
830 printk(KERN_DEBUG "original variable MTRRs\n"); 829 printk(KERN_DEBUG "original variable MTRRs\n");
831 print_out_mtrr_range_state(); 830 print_out_mtrr_range_state();
832 831
833 memset(range, 0, sizeof(range)); 832 memset(range, 0, sizeof(range));
834 extra_remove_size = 0; 833 x_remove_size = 0;
835 extra_remove_base = 1 << (32 - PAGE_SHIFT); 834 x_remove_base = 1 << (32 - PAGE_SHIFT);
836 if (mtrr_tom2) 835 if (mtrr_tom2)
837 extra_remove_size = 836 x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base;
838 (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base; 837
839 nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base, 838 nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size);
840 extra_remove_size);
841 /* 839 /*
842 * [0, 1M) should always be coverred by var mtrr with WB 840 * [0, 1M) should always be covered by var mtrr with WB
843 * and fixed mtrrs should take effective before var mtrr for it 841 * and fixed mtrrs should take effect before var mtrr for it:
844 */ 842 */
845 nr_range = add_range_with_merge(range, nr_range, 0, 843 nr_range = add_range_with_merge(range, nr_range, 0,
846 (1ULL<<(20 - PAGE_SHIFT)) - 1); 844 (1ULL<<(20 - PAGE_SHIFT)) - 1);
847 /* sort the ranges */ 845 /* Sort the ranges: */
848 sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); 846 sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
849 847
850 range_sums = sum_ranges(range, nr_range); 848 range_sums = sum_ranges(range, nr_range);
@@ -854,7 +852,7 @@ int __init mtrr_cleanup(unsigned address_bits)
854 if (mtrr_chunk_size && mtrr_gran_size) { 852 if (mtrr_chunk_size && mtrr_gran_size) {
855 i = 0; 853 i = 0;
856 mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size, 854 mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size,
857 extra_remove_base, extra_remove_size, i); 855 x_remove_base, x_remove_size, i);
858 856
859 mtrr_print_out_one_result(i); 857 mtrr_print_out_one_result(i);
860 858
@@ -880,7 +878,7 @@ int __init mtrr_cleanup(unsigned address_bits)
880 continue; 878 continue;
881 879
882 mtrr_calc_range_state(chunk_size, gran_size, 880 mtrr_calc_range_state(chunk_size, gran_size,
883 extra_remove_base, extra_remove_size, i); 881 x_remove_base, x_remove_size, i);
884 if (debug_print) { 882 if (debug_print) {
885 mtrr_print_out_one_result(i); 883 mtrr_print_out_one_result(i);
886 printk(KERN_INFO "\n"); 884 printk(KERN_INFO "\n");
@@ -890,7 +888,7 @@ int __init mtrr_cleanup(unsigned address_bits)
890 } 888 }
891 } 889 }
892 890
893 /* try to find the optimal index */ 891 /* Try to find the optimal index: */
894 index_good = mtrr_search_optimal_index(); 892 index_good = mtrr_search_optimal_index();
895 893
896 if (index_good != -1) { 894 if (index_good != -1) {
@@ -898,7 +896,7 @@ int __init mtrr_cleanup(unsigned address_bits)
898 i = index_good; 896 i = index_good;
899 mtrr_print_out_one_result(i); 897 mtrr_print_out_one_result(i);
900 898
901 /* convert ranges to var ranges state */ 899 /* Convert ranges to var ranges state: */
902 chunk_size = result[i].chunk_sizek; 900 chunk_size = result[i].chunk_sizek;
903 chunk_size <<= 10; 901 chunk_size <<= 10;
904 gran_size = result[i].gran_sizek; 902 gran_size = result[i].gran_sizek;
@@ -941,8 +939,8 @@ early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
941 * Note this won't check if the MTRRs < 4GB where the magic bit doesn't 939 * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
942 * apply to are wrong, but so far we don't know of any such case in the wild. 940 * apply to are wrong, but so far we don't know of any such case in the wild.
943 */ 941 */
944#define Tom2Enabled (1U << 21) 942#define Tom2Enabled (1U << 21)
945#define Tom2ForceMemTypeWB (1U << 22) 943#define Tom2ForceMemTypeWB (1U << 22)
946 944
947int __init amd_special_default_mtrr(void) 945int __init amd_special_default_mtrr(void)
948{ 946{
@@ -952,7 +950,7 @@ int __init amd_special_default_mtrr(void)
952 return 0; 950 return 0;
953 if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) 951 if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
954 return 0; 952 return 0;
955 /* In case some hypervisor doesn't pass SYSCFG through */ 953 /* In case some hypervisor doesn't pass SYSCFG through: */
956 if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) 954 if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
957 return 0; 955 return 0;
958 /* 956 /*
@@ -965,19 +963,21 @@ int __init amd_special_default_mtrr(void)
965 return 0; 963 return 0;
966} 964}
967 965
968static u64 __init real_trim_memory(unsigned long start_pfn, 966static u64 __init
969 unsigned long limit_pfn) 967real_trim_memory(unsigned long start_pfn, unsigned long limit_pfn)
970{ 968{
971 u64 trim_start, trim_size; 969 u64 trim_start, trim_size;
970
972 trim_start = start_pfn; 971 trim_start = start_pfn;
973 trim_start <<= PAGE_SHIFT; 972 trim_start <<= PAGE_SHIFT;
973
974 trim_size = limit_pfn; 974 trim_size = limit_pfn;
975 trim_size <<= PAGE_SHIFT; 975 trim_size <<= PAGE_SHIFT;
976 trim_size -= trim_start; 976 trim_size -= trim_start;
977 977
978 return e820_update_range(trim_start, trim_size, E820_RAM, 978 return e820_update_range(trim_start, trim_size, E820_RAM, E820_RESERVED);
979 E820_RESERVED);
980} 979}
980
981/** 981/**
982 * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs 982 * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
983 * @end_pfn: ending page frame number 983 * @end_pfn: ending page frame number
@@ -985,7 +985,7 @@ static u64 __init real_trim_memory(unsigned long start_pfn,
985 * Some buggy BIOSes don't setup the MTRRs properly for systems with certain 985 * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
986 * memory configurations. This routine checks that the highest MTRR matches 986 * memory configurations. This routine checks that the highest MTRR matches
987 * the end of memory, to make sure the MTRRs having a write back type cover 987 * the end of memory, to make sure the MTRRs having a write back type cover
988 * all of the memory the kernel is intending to use. If not, it'll trim any 988 * all of the memory the kernel is intending to use. If not, it'll trim any
989 * memory off the end by adjusting end_pfn, removing it from the kernel's 989 * memory off the end by adjusting end_pfn, removing it from the kernel's
990 * allocation pools, warning the user with an obnoxious message. 990 * allocation pools, warning the user with an obnoxious message.
991 */ 991 */
@@ -994,21 +994,22 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
994 unsigned long i, base, size, highest_pfn = 0, def, dummy; 994 unsigned long i, base, size, highest_pfn = 0, def, dummy;
995 mtrr_type type; 995 mtrr_type type;
996 u64 total_trim_size; 996 u64 total_trim_size;
997
998 /* extra one for all 0 */ 997 /* extra one for all 0 */
999 int num[MTRR_NUM_TYPES + 1]; 998 int num[MTRR_NUM_TYPES + 1];
999
1000 /* 1000 /*
1001 * Make sure we only trim uncachable memory on machines that 1001 * Make sure we only trim uncachable memory on machines that
1002 * support the Intel MTRR architecture: 1002 * support the Intel MTRR architecture:
1003 */ 1003 */
1004 if (!is_cpu(INTEL) || disable_mtrr_trim) 1004 if (!is_cpu(INTEL) || disable_mtrr_trim)
1005 return 0; 1005 return 0;
1006
1006 rdmsr(MSR_MTRRdefType, def, dummy); 1007 rdmsr(MSR_MTRRdefType, def, dummy);
1007 def &= 0xff; 1008 def &= 0xff;
1008 if (def != MTRR_TYPE_UNCACHABLE) 1009 if (def != MTRR_TYPE_UNCACHABLE)
1009 return 0; 1010 return 0;
1010 1011
1011 /* get it and store it aside */ 1012 /* Get it and store it aside: */
1012 memset(range_state, 0, sizeof(range_state)); 1013 memset(range_state, 0, sizeof(range_state));
1013 for (i = 0; i < num_var_ranges; i++) { 1014 for (i = 0; i < num_var_ranges; i++) {
1014 mtrr_if->get(i, &base, &size, &type); 1015 mtrr_if->get(i, &base, &size, &type);
@@ -1017,7 +1018,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
1017 range_state[i].type = type; 1018 range_state[i].type = type;
1018 } 1019 }
1019 1020
1020 /* Find highest cached pfn */ 1021 /* Find highest cached pfn: */
1021 for (i = 0; i < num_var_ranges; i++) { 1022 for (i = 0; i < num_var_ranges; i++) {
1022 type = range_state[i].type; 1023 type = range_state[i].type;
1023 if (type != MTRR_TYPE_WRBACK) 1024 if (type != MTRR_TYPE_WRBACK)
@@ -1028,13 +1029,13 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
1028 highest_pfn = base + size; 1029 highest_pfn = base + size;
1029 } 1030 }
1030 1031
1031 /* kvm/qemu doesn't have mtrr set right, don't trim them all */ 1032 /* kvm/qemu doesn't have mtrr set right, don't trim them all: */
1032 if (!highest_pfn) { 1033 if (!highest_pfn) {
1033 printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); 1034 printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
1034 return 0; 1035 return 0;
1035 } 1036 }
1036 1037
1037 /* check entries number */ 1038 /* Check entries number: */
1038 memset(num, 0, sizeof(num)); 1039 memset(num, 0, sizeof(num));
1039 for (i = 0; i < num_var_ranges; i++) { 1040 for (i = 0; i < num_var_ranges; i++) {
1040 type = range_state[i].type; 1041 type = range_state[i].type;
@@ -1046,11 +1047,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
1046 num[type]++; 1047 num[type]++;
1047 } 1048 }
1048 1049
1049 /* no entry for WB? */ 1050 /* No entry for WB? */
1050 if (!num[MTRR_TYPE_WRBACK]) 1051 if (!num[MTRR_TYPE_WRBACK])
1051 return 0; 1052 return 0;
1052 1053
1053 /* check if we only had WB and UC */ 1054 /* Check if we only had WB and UC: */
1054 if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != 1055 if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
1055 num_var_ranges - num[MTRR_NUM_TYPES]) 1056 num_var_ranges - num[MTRR_NUM_TYPES])
1056 return 0; 1057 return 0;
@@ -1066,31 +1067,31 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
1066 } 1067 }
1067 nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0); 1068 nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
1068 1069
1070 /* Check the head: */
1069 total_trim_size = 0; 1071 total_trim_size = 0;
1070 /* check the head */
1071 if (range[0].start) 1072 if (range[0].start)
1072 total_trim_size += real_trim_memory(0, range[0].start); 1073 total_trim_size += real_trim_memory(0, range[0].start);
1073 /* check the holes */ 1074
1075 /* Check the holes: */
1074 for (i = 0; i < nr_range - 1; i++) { 1076 for (i = 0; i < nr_range - 1; i++) {
1075 if (range[i].end + 1 < range[i+1].start) 1077 if (range[i].end + 1 < range[i+1].start)
1076 total_trim_size += real_trim_memory(range[i].end + 1, 1078 total_trim_size += real_trim_memory(range[i].end + 1,
1077 range[i+1].start); 1079 range[i+1].start);
1078 } 1080 }
1079 /* check the top */ 1081
1082 /* Check the top: */
1080 i = nr_range - 1; 1083 i = nr_range - 1;
1081 if (range[i].end + 1 < end_pfn) 1084 if (range[i].end + 1 < end_pfn)
1082 total_trim_size += real_trim_memory(range[i].end + 1, 1085 total_trim_size += real_trim_memory(range[i].end + 1,
1083 end_pfn); 1086 end_pfn);
1084 1087
1085 if (total_trim_size) { 1088 if (total_trim_size) {
1086 printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover" 1089 pr_warning("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", total_trim_size >> 20);
1087 " all of memory, losing %lluMB of RAM.\n",
1088 total_trim_size >> 20);
1089 1090
1090 if (!changed_by_mtrr_cleanup) 1091 if (!changed_by_mtrr_cleanup)
1091 WARN_ON(1); 1092 WARN_ON(1);
1092 1093
1093 printk(KERN_INFO "update e820 for mtrr\n"); 1094 pr_info("update e820 for mtrr\n");
1094 update_e820(); 1095 update_e820();
1095 1096
1096 return 1; 1097 return 1;
@@ -1098,4 +1099,3 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
1098 1099
1099 return 0; 1100 return 0;
1100} 1101}
1101
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
index ff14c320040c..228d982ce09c 100644
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -1,38 +1,40 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/io.h>
2#include <linux/mm.h> 3#include <linux/mm.h>
3#include <asm/mtrr.h> 4
4#include <asm/msr.h>
5#include <asm/io.h>
6#include <asm/processor-cyrix.h> 5#include <asm/processor-cyrix.h>
7#include <asm/processor-flags.h> 6#include <asm/processor-flags.h>
7#include <asm/mtrr.h>
8#include <asm/msr.h>
9
8#include "mtrr.h" 10#include "mtrr.h"
9 11
10static void 12static void
11cyrix_get_arr(unsigned int reg, unsigned long *base, 13cyrix_get_arr(unsigned int reg, unsigned long *base,
12 unsigned long *size, mtrr_type * type) 14 unsigned long *size, mtrr_type * type)
13{ 15{
14 unsigned long flags;
15 unsigned char arr, ccr3, rcr, shift; 16 unsigned char arr, ccr3, rcr, shift;
17 unsigned long flags;
16 18
17 arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ 19 arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
18 20
19 /* Save flags and disable interrupts */
20 local_irq_save(flags); 21 local_irq_save(flags);
21 22
22 ccr3 = getCx86(CX86_CCR3); 23 ccr3 = getCx86(CX86_CCR3);
23 setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ 24 setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
24 ((unsigned char *) base)[3] = getCx86(arr); 25 ((unsigned char *)base)[3] = getCx86(arr);
25 ((unsigned char *) base)[2] = getCx86(arr + 1); 26 ((unsigned char *)base)[2] = getCx86(arr + 1);
26 ((unsigned char *) base)[1] = getCx86(arr + 2); 27 ((unsigned char *)base)[1] = getCx86(arr + 2);
27 rcr = getCx86(CX86_RCR_BASE + reg); 28 rcr = getCx86(CX86_RCR_BASE + reg);
28 setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ 29 setCx86(CX86_CCR3, ccr3); /* disable MAPEN */
29 30
30 /* Enable interrupts if it was enabled previously */
31 local_irq_restore(flags); 31 local_irq_restore(flags);
32
32 shift = ((unsigned char *) base)[1] & 0x0f; 33 shift = ((unsigned char *) base)[1] & 0x0f;
33 *base >>= PAGE_SHIFT; 34 *base >>= PAGE_SHIFT;
34 35
35 /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7 36 /*
37 * Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
36 * Note: shift==0xf means 4G, this is unsupported. 38 * Note: shift==0xf means 4G, this is unsupported.
37 */ 39 */
38 if (shift) 40 if (shift)
@@ -76,17 +78,20 @@ cyrix_get_arr(unsigned int reg, unsigned long *base,
76 } 78 }
77} 79}
78 80
81/*
82 * cyrix_get_free_region - get a free ARR.
83 *
84 * @base: the starting (base) address of the region.
85 * @size: the size (in bytes) of the region.
86 *
87 * Returns: the index of the region on success, else -1 on error.
88*/
79static int 89static int
80cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) 90cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
81/* [SUMMARY] Get a free ARR.
82 <base> The starting (base) address of the region.
83 <size> The size (in bytes) of the region.
84 [RETURNS] The index of the region on success, else -1 on error.
85*/
86{ 91{
87 int i;
88 mtrr_type ltype;
89 unsigned long lbase, lsize; 92 unsigned long lbase, lsize;
93 mtrr_type ltype;
94 int i;
90 95
91 switch (replace_reg) { 96 switch (replace_reg) {
92 case 7: 97 case 7:
@@ -107,14 +112,17 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
107 cyrix_get_arr(7, &lbase, &lsize, &ltype); 112 cyrix_get_arr(7, &lbase, &lsize, &ltype);
108 if (lsize == 0) 113 if (lsize == 0)
109 return 7; 114 return 7;
110 /* Else try ARR0-ARR6 first */ 115 /* Else try ARR0-ARR6 first */
111 } else { 116 } else {
112 for (i = 0; i < 7; i++) { 117 for (i = 0; i < 7; i++) {
113 cyrix_get_arr(i, &lbase, &lsize, &ltype); 118 cyrix_get_arr(i, &lbase, &lsize, &ltype);
114 if (lsize == 0) 119 if (lsize == 0)
115 return i; 120 return i;
116 } 121 }
117 /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */ 122 /*
123 * ARR0-ARR6 isn't free
124 * try ARR7 but its size must be at least 256K
125 */
118 cyrix_get_arr(i, &lbase, &lsize, &ltype); 126 cyrix_get_arr(i, &lbase, &lsize, &ltype);
119 if ((lsize == 0) && (size >= 0x40)) 127 if ((lsize == 0) && (size >= 0x40))
120 return i; 128 return i;
@@ -122,21 +130,22 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
122 return -ENOSPC; 130 return -ENOSPC;
123} 131}
124 132
125static u32 cr4 = 0; 133static u32 cr4, ccr3;
126static u32 ccr3;
127 134
128static void prepare_set(void) 135static void prepare_set(void)
129{ 136{
130 u32 cr0; 137 u32 cr0;
131 138
132 /* Save value of CR4 and clear Page Global Enable (bit 7) */ 139 /* Save value of CR4 and clear Page Global Enable (bit 7) */
133 if ( cpu_has_pge ) { 140 if (cpu_has_pge) {
134 cr4 = read_cr4(); 141 cr4 = read_cr4();
135 write_cr4(cr4 & ~X86_CR4_PGE); 142 write_cr4(cr4 & ~X86_CR4_PGE);
136 } 143 }
137 144
138 /* Disable and flush caches. Note that wbinvd flushes the TLBs as 145 /*
139 a side-effect */ 146 * Disable and flush caches.
147 * Note that wbinvd flushes the TLBs as a side-effect
148 */
140 cr0 = read_cr0() | X86_CR0_CD; 149 cr0 = read_cr0() | X86_CR0_CD;
141 wbinvd(); 150 wbinvd();
142 write_cr0(cr0); 151 write_cr0(cr0);
@@ -147,22 +156,21 @@ static void prepare_set(void)
147 156
148 /* Cyrix ARRs - everything else was excluded at the top */ 157 /* Cyrix ARRs - everything else was excluded at the top */
149 setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); 158 setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
150
151} 159}
152 160
153static void post_set(void) 161static void post_set(void)
154{ 162{
155 /* Flush caches and TLBs */ 163 /* Flush caches and TLBs */
156 wbinvd(); 164 wbinvd();
157 165
158 /* Cyrix ARRs - everything else was excluded at the top */ 166 /* Cyrix ARRs - everything else was excluded at the top */
159 setCx86(CX86_CCR3, ccr3); 167 setCx86(CX86_CCR3, ccr3);
160 168
161 /* Enable caches */ 169 /* Enable caches */
162 write_cr0(read_cr0() & 0xbfffffff); 170 write_cr0(read_cr0() & 0xbfffffff);
163 171
164 /* Restore value of CR4 */ 172 /* Restore value of CR4 */
165 if ( cpu_has_pge ) 173 if (cpu_has_pge)
166 write_cr4(cr4); 174 write_cr4(cr4);
167} 175}
168 176
@@ -178,7 +186,8 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
178 size >>= 6; 186 size >>= 6;
179 187
180 size &= 0x7fff; /* make sure arr_size <= 14 */ 188 size &= 0x7fff; /* make sure arr_size <= 14 */
181 for (arr_size = 0; size; arr_size++, size >>= 1) ; 189 for (arr_size = 0; size; arr_size++, size >>= 1)
190 ;
182 191
183 if (reg < 7) { 192 if (reg < 7) {
184 switch (type) { 193 switch (type) {
@@ -215,18 +224,18 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
215 prepare_set(); 224 prepare_set();
216 225
217 base <<= PAGE_SHIFT; 226 base <<= PAGE_SHIFT;
218 setCx86(arr, ((unsigned char *) &base)[3]); 227 setCx86(arr + 0, ((unsigned char *)&base)[3]);
219 setCx86(arr + 1, ((unsigned char *) &base)[2]); 228 setCx86(arr + 1, ((unsigned char *)&base)[2]);
220 setCx86(arr + 2, (((unsigned char *) &base)[1]) | arr_size); 229 setCx86(arr + 2, (((unsigned char *)&base)[1]) | arr_size);
221 setCx86(CX86_RCR_BASE + reg, arr_type); 230 setCx86(CX86_RCR_BASE + reg, arr_type);
222 231
223 post_set(); 232 post_set();
224} 233}
225 234
226typedef struct { 235typedef struct {
227 unsigned long base; 236 unsigned long base;
228 unsigned long size; 237 unsigned long size;
229 mtrr_type type; 238 mtrr_type type;
230} arr_state_t; 239} arr_state_t;
231 240
232static arr_state_t arr_state[8] = { 241static arr_state_t arr_state[8] = {
@@ -247,16 +256,17 @@ static void cyrix_set_all(void)
247 setCx86(CX86_CCR0 + i, ccr_state[i]); 256 setCx86(CX86_CCR0 + i, ccr_state[i]);
248 for (; i < 7; i++) 257 for (; i < 7; i++)
249 setCx86(CX86_CCR4 + i, ccr_state[i]); 258 setCx86(CX86_CCR4 + i, ccr_state[i]);
250 for (i = 0; i < 8; i++) 259
251 cyrix_set_arr(i, arr_state[i].base, 260 for (i = 0; i < 8; i++) {
261 cyrix_set_arr(i, arr_state[i].base,
252 arr_state[i].size, arr_state[i].type); 262 arr_state[i].size, arr_state[i].type);
263 }
253 264
254 post_set(); 265 post_set();
255} 266}
256 267
257static struct mtrr_ops cyrix_mtrr_ops = { 268static struct mtrr_ops cyrix_mtrr_ops = {
258 .vendor = X86_VENDOR_CYRIX, 269 .vendor = X86_VENDOR_CYRIX,
259// .init = cyrix_arr_init,
260 .set_all = cyrix_set_all, 270 .set_all = cyrix_set_all,
261 .set = cyrix_set_arr, 271 .set = cyrix_set_arr,
262 .get = cyrix_get_arr, 272 .get = cyrix_get_arr,
@@ -270,5 +280,3 @@ int __init cyrix_init_mtrr(void)
270 set_mtrr_ops(&cyrix_mtrr_ops); 280 set_mtrr_ops(&cyrix_mtrr_ops);
271 return 0; 281 return 0;
272} 282}
273
274//arch_initcall(cyrix_init_mtrr);
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 0543f69f0b27..55da0c5f68dd 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -1,28 +1,34 @@
1/* This only handles 32bit MTRR on 32bit hosts. This is strictly wrong 1/*
2 because MTRRs can span upto 40 bits (36bits on most modern x86) */ 2 * This only handles 32bit MTRR on 32bit hosts. This is strictly wrong
3 * because MTRRs can span upto 40 bits (36bits on most modern x86)
4 */
5#define DEBUG
6
7#include <linux/module.h>
3#include <linux/init.h> 8#include <linux/init.h>
4#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/io.h>
5#include <linux/mm.h> 11#include <linux/mm.h>
6#include <linux/module.h> 12
7#include <asm/io.h>
8#include <asm/mtrr.h>
9#include <asm/msr.h>
10#include <asm/system.h>
11#include <asm/cpufeature.h>
12#include <asm/processor-flags.h> 13#include <asm/processor-flags.h>
14#include <asm/cpufeature.h>
13#include <asm/tlbflush.h> 15#include <asm/tlbflush.h>
16#include <asm/system.h>
17#include <asm/mtrr.h>
18#include <asm/msr.h>
14#include <asm/pat.h> 19#include <asm/pat.h>
20
15#include "mtrr.h" 21#include "mtrr.h"
16 22
17struct fixed_range_block { 23struct fixed_range_block {
18 int base_msr; /* start address of an MTRR block */ 24 int base_msr; /* start address of an MTRR block */
19 int ranges; /* number of MTRRs in this block */ 25 int ranges; /* number of MTRRs in this block */
20}; 26};
21 27
22static struct fixed_range_block fixed_range_blocks[] = { 28static struct fixed_range_block fixed_range_blocks[] = {
23 { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */ 29 { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */
24 { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */ 30 { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */
25 { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */ 31 { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */
26 {} 32 {}
27}; 33};
28 34
@@ -30,10 +36,10 @@ static unsigned long smp_changes_mask;
30static int mtrr_state_set; 36static int mtrr_state_set;
31u64 mtrr_tom2; 37u64 mtrr_tom2;
32 38
33struct mtrr_state_type mtrr_state = {}; 39struct mtrr_state_type mtrr_state;
34EXPORT_SYMBOL_GPL(mtrr_state); 40EXPORT_SYMBOL_GPL(mtrr_state);
35 41
36/** 42/*
37 * BIOS is expected to clear MtrrFixDramModEn bit, see for example 43 * BIOS is expected to clear MtrrFixDramModEn bit, see for example
38 * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD 44 * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
39 * Opteron Processors" (26094 Rev. 3.30 February 2006), section 45 * Opteron Processors" (26094 Rev. 3.30 February 2006), section
@@ -104,9 +110,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
104 * Look of multiple ranges matching this address and pick type 110 * Look of multiple ranges matching this address and pick type
105 * as per MTRR precedence 111 * as per MTRR precedence
106 */ 112 */
107 if (!(mtrr_state.enabled & 2)) { 113 if (!(mtrr_state.enabled & 2))
108 return mtrr_state.def_type; 114 return mtrr_state.def_type;
109 }
110 115
111 prev_match = 0xFF; 116 prev_match = 0xFF;
112 for (i = 0; i < num_var_ranges; ++i) { 117 for (i = 0; i < num_var_ranges; ++i) {
@@ -125,9 +130,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
125 if (start_state != end_state) 130 if (start_state != end_state)
126 return 0xFE; 131 return 0xFE;
127 132
128 if ((start & mask) != (base & mask)) { 133 if ((start & mask) != (base & mask))
129 continue; 134 continue;
130 }
131 135
132 curr_match = mtrr_state.var_ranges[i].base_lo & 0xff; 136 curr_match = mtrr_state.var_ranges[i].base_lo & 0xff;
133 if (prev_match == 0xFF) { 137 if (prev_match == 0xFF) {
@@ -148,9 +152,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
148 curr_match = MTRR_TYPE_WRTHROUGH; 152 curr_match = MTRR_TYPE_WRTHROUGH;
149 } 153 }
150 154
151 if (prev_match != curr_match) { 155 if (prev_match != curr_match)
152 return MTRR_TYPE_UNCACHABLE; 156 return MTRR_TYPE_UNCACHABLE;
153 }
154 } 157 }
155 158
156 if (mtrr_tom2) { 159 if (mtrr_tom2) {
@@ -164,7 +167,7 @@ u8 mtrr_type_lookup(u64 start, u64 end)
164 return mtrr_state.def_type; 167 return mtrr_state.def_type;
165} 168}
166 169
167/* Get the MSR pair relating to a var range */ 170/* Get the MSR pair relating to a var range */
168static void 171static void
169get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) 172get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
170{ 173{
@@ -172,7 +175,7 @@ get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
172 rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); 175 rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
173} 176}
174 177
175/* fill the MSR pair relating to a var range */ 178/* Fill the MSR pair relating to a var range */
176void fill_mtrr_var_range(unsigned int index, 179void fill_mtrr_var_range(unsigned int index,
177 u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi) 180 u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi)
178{ 181{
@@ -186,10 +189,9 @@ void fill_mtrr_var_range(unsigned int index,
186 vr[index].mask_hi = mask_hi; 189 vr[index].mask_hi = mask_hi;
187} 190}
188 191
189static void 192static void get_fixed_ranges(mtrr_type *frs)
190get_fixed_ranges(mtrr_type * frs)
191{ 193{
192 unsigned int *p = (unsigned int *) frs; 194 unsigned int *p = (unsigned int *)frs;
193 int i; 195 int i;
194 196
195 k8_check_syscfg_dram_mod_en(); 197 k8_check_syscfg_dram_mod_en();
@@ -217,22 +219,22 @@ static void __init print_fixed_last(void)
217 if (!last_fixed_end) 219 if (!last_fixed_end)
218 return; 220 return;
219 221
220 printk(KERN_DEBUG " %05X-%05X %s\n", last_fixed_start, 222 pr_debug(" %05X-%05X %s\n", last_fixed_start,
221 last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type)); 223 last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type));
222 224
223 last_fixed_end = 0; 225 last_fixed_end = 0;
224} 226}
225 227
226static void __init update_fixed_last(unsigned base, unsigned end, 228static void __init update_fixed_last(unsigned base, unsigned end,
227 mtrr_type type) 229 mtrr_type type)
228{ 230{
229 last_fixed_start = base; 231 last_fixed_start = base;
230 last_fixed_end = end; 232 last_fixed_end = end;
231 last_fixed_type = type; 233 last_fixed_type = type;
232} 234}
233 235
234static void __init print_fixed(unsigned base, unsigned step, 236static void __init
235 const mtrr_type *types) 237print_fixed(unsigned base, unsigned step, const mtrr_type *types)
236{ 238{
237 unsigned i; 239 unsigned i;
238 240
@@ -259,54 +261,55 @@ static void __init print_mtrr_state(void)
259 unsigned int i; 261 unsigned int i;
260 int high_width; 262 int high_width;
261 263
262 printk(KERN_DEBUG "MTRR default type: %s\n", 264 pr_debug("MTRR default type: %s\n",
263 mtrr_attrib_to_str(mtrr_state.def_type)); 265 mtrr_attrib_to_str(mtrr_state.def_type));
264 if (mtrr_state.have_fixed) { 266 if (mtrr_state.have_fixed) {
265 printk(KERN_DEBUG "MTRR fixed ranges %sabled:\n", 267 pr_debug("MTRR fixed ranges %sabled:\n",
266 mtrr_state.enabled & 1 ? "en" : "dis"); 268 mtrr_state.enabled & 1 ? "en" : "dis");
267 print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); 269 print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
268 for (i = 0; i < 2; ++i) 270 for (i = 0; i < 2; ++i)
269 print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); 271 print_fixed(0x80000 + i * 0x20000, 0x04000,
272 mtrr_state.fixed_ranges + (i + 1) * 8);
270 for (i = 0; i < 8; ++i) 273 for (i = 0; i < 8; ++i)
271 print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); 274 print_fixed(0xC0000 + i * 0x08000, 0x01000,
275 mtrr_state.fixed_ranges + (i + 3) * 8);
272 276
273 /* tail */ 277 /* tail */
274 print_fixed_last(); 278 print_fixed_last();
275 } 279 }
276 printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", 280 pr_debug("MTRR variable ranges %sabled:\n",
277 mtrr_state.enabled & 2 ? "en" : "dis"); 281 mtrr_state.enabled & 2 ? "en" : "dis");
278 if (size_or_mask & 0xffffffffUL) 282 if (size_or_mask & 0xffffffffUL)
279 high_width = ffs(size_or_mask & 0xffffffffUL) - 1; 283 high_width = ffs(size_or_mask & 0xffffffffUL) - 1;
280 else 284 else
281 high_width = ffs(size_or_mask>>32) + 32 - 1; 285 high_width = ffs(size_or_mask>>32) + 32 - 1;
282 high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; 286 high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4;
287
283 for (i = 0; i < num_var_ranges; ++i) { 288 for (i = 0; i < num_var_ranges; ++i) {
284 if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) 289 if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
285 printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", 290 pr_debug(" %u base %0*X%05X000 mask %0*X%05X000 %s\n",
286 i, 291 i,
287 high_width, 292 high_width,
288 mtrr_state.var_ranges[i].base_hi, 293 mtrr_state.var_ranges[i].base_hi,
289 mtrr_state.var_ranges[i].base_lo >> 12, 294 mtrr_state.var_ranges[i].base_lo >> 12,
290 high_width, 295 high_width,
291 mtrr_state.var_ranges[i].mask_hi, 296 mtrr_state.var_ranges[i].mask_hi,
292 mtrr_state.var_ranges[i].mask_lo >> 12, 297 mtrr_state.var_ranges[i].mask_lo >> 12,
293 mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); 298 mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
294 else 299 else
295 printk(KERN_DEBUG " %u disabled\n", i); 300 pr_debug(" %u disabled\n", i);
296 }
297 if (mtrr_tom2) {
298 printk(KERN_DEBUG "TOM2: %016llx aka %lldM\n",
299 mtrr_tom2, mtrr_tom2>>20);
300 } 301 }
302 if (mtrr_tom2)
303 pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20);
301} 304}
302 305
303/* Grab all of the MTRR state for this CPU into *state */ 306/* Grab all of the MTRR state for this CPU into *state */
304void __init get_mtrr_state(void) 307void __init get_mtrr_state(void)
305{ 308{
306 unsigned int i;
307 struct mtrr_var_range *vrs; 309 struct mtrr_var_range *vrs;
308 unsigned lo, dummy;
309 unsigned long flags; 310 unsigned long flags;
311 unsigned lo, dummy;
312 unsigned int i;
310 313
311 vrs = mtrr_state.var_ranges; 314 vrs = mtrr_state.var_ranges;
312 315
@@ -324,6 +327,7 @@ void __init get_mtrr_state(void)
324 327
325 if (amd_special_default_mtrr()) { 328 if (amd_special_default_mtrr()) {
326 unsigned low, high; 329 unsigned low, high;
330
327 /* TOP_MEM2 */ 331 /* TOP_MEM2 */
328 rdmsr(MSR_K8_TOP_MEM2, low, high); 332 rdmsr(MSR_K8_TOP_MEM2, low, high);
329 mtrr_tom2 = high; 333 mtrr_tom2 = high;
@@ -344,10 +348,9 @@ void __init get_mtrr_state(void)
344 348
345 post_set(); 349 post_set();
346 local_irq_restore(flags); 350 local_irq_restore(flags);
347
348} 351}
349 352
350/* Some BIOS's are fucked and don't set all MTRRs the same! */ 353/* Some BIOS's are messed up and don't set all MTRRs the same! */
351void __init mtrr_state_warn(void) 354void __init mtrr_state_warn(void)
352{ 355{
353 unsigned long mask = smp_changes_mask; 356 unsigned long mask = smp_changes_mask;
@@ -355,28 +358,33 @@ void __init mtrr_state_warn(void)
355 if (!mask) 358 if (!mask)
356 return; 359 return;
357 if (mask & MTRR_CHANGE_MASK_FIXED) 360 if (mask & MTRR_CHANGE_MASK_FIXED)
358 printk(KERN_WARNING "mtrr: your CPUs had inconsistent fixed MTRR settings\n"); 361 pr_warning("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
359 if (mask & MTRR_CHANGE_MASK_VARIABLE) 362 if (mask & MTRR_CHANGE_MASK_VARIABLE)
360 printk(KERN_WARNING "mtrr: your CPUs had inconsistent variable MTRR settings\n"); 363 pr_warning("mtrr: your CPUs had inconsistent variable MTRR settings\n");
361 if (mask & MTRR_CHANGE_MASK_DEFTYPE) 364 if (mask & MTRR_CHANGE_MASK_DEFTYPE)
362 printk(KERN_WARNING "mtrr: your CPUs had inconsistent MTRRdefType settings\n"); 365 pr_warning("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
366
363 printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n"); 367 printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n");
364 printk(KERN_INFO "mtrr: corrected configuration.\n"); 368 printk(KERN_INFO "mtrr: corrected configuration.\n");
365} 369}
366 370
367/* Doesn't attempt to pass an error out to MTRR users 371/*
368 because it's quite complicated in some cases and probably not 372 * Doesn't attempt to pass an error out to MTRR users
369 worth it because the best error handling is to ignore it. */ 373 * because it's quite complicated in some cases and probably not
374 * worth it because the best error handling is to ignore it.
375 */
370void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) 376void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
371{ 377{
372 if (wrmsr_safe(msr, a, b) < 0) 378 if (wrmsr_safe(msr, a, b) < 0) {
373 printk(KERN_ERR 379 printk(KERN_ERR
374 "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n", 380 "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
375 smp_processor_id(), msr, a, b); 381 smp_processor_id(), msr, a, b);
382 }
376} 383}
377 384
378/** 385/**
379 * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have 386 * set_fixed_range - checks & updates a fixed-range MTRR if it
387 * differs from the value it should have
380 * @msr: MSR address of the MTTR which should be checked and updated 388 * @msr: MSR address of the MTTR which should be checked and updated
381 * @changed: pointer which indicates whether the MTRR needed to be changed 389 * @changed: pointer which indicates whether the MTRR needed to be changed
382 * @msrwords: pointer to the MSR values which the MSR should have 390 * @msrwords: pointer to the MSR values which the MSR should have
@@ -401,20 +409,23 @@ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
401 * 409 *
402 * Returns: The index of the region on success, else negative on error. 410 * Returns: The index of the region on success, else negative on error.
403 */ 411 */
404int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) 412int
413generic_get_free_region(unsigned long base, unsigned long size, int replace_reg)
405{ 414{
406 int i, max;
407 mtrr_type ltype;
408 unsigned long lbase, lsize; 415 unsigned long lbase, lsize;
416 mtrr_type ltype;
417 int i, max;
409 418
410 max = num_var_ranges; 419 max = num_var_ranges;
411 if (replace_reg >= 0 && replace_reg < max) 420 if (replace_reg >= 0 && replace_reg < max)
412 return replace_reg; 421 return replace_reg;
422
413 for (i = 0; i < max; ++i) { 423 for (i = 0; i < max; ++i) {
414 mtrr_if->get(i, &lbase, &lsize, &ltype); 424 mtrr_if->get(i, &lbase, &lsize, &ltype);
415 if (lsize == 0) 425 if (lsize == 0)
416 return i; 426 return i;
417 } 427 }
428
418 return -ENOSPC; 429 return -ENOSPC;
419} 430}
420 431
@@ -434,7 +445,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
434 rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); 445 rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
435 446
436 if ((mask_lo & 0x800) == 0) { 447 if ((mask_lo & 0x800) == 0) {
437 /* Invalid (i.e. free) range */ 448 /* Invalid (i.e. free) range */
438 *base = 0; 449 *base = 0;
439 *size = 0; 450 *size = 0;
440 *type = 0; 451 *type = 0;
@@ -471,27 +482,31 @@ out_put_cpu:
471} 482}
472 483
473/** 484/**
474 * set_fixed_ranges - checks & updates the fixed-range MTRRs if they differ from the saved set 485 * set_fixed_ranges - checks & updates the fixed-range MTRRs if they
486 * differ from the saved set
475 * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges() 487 * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges()
476 */ 488 */
477static int set_fixed_ranges(mtrr_type * frs) 489static int set_fixed_ranges(mtrr_type *frs)
478{ 490{
479 unsigned long long *saved = (unsigned long long *) frs; 491 unsigned long long *saved = (unsigned long long *)frs;
480 bool changed = false; 492 bool changed = false;
481 int block=-1, range; 493 int block = -1, range;
482 494
483 k8_check_syscfg_dram_mod_en(); 495 k8_check_syscfg_dram_mod_en();
484 496
485 while (fixed_range_blocks[++block].ranges) 497 while (fixed_range_blocks[++block].ranges) {
486 for (range=0; range < fixed_range_blocks[block].ranges; range++) 498 for (range = 0; range < fixed_range_blocks[block].ranges; range++)
487 set_fixed_range(fixed_range_blocks[block].base_msr + range, 499 set_fixed_range(fixed_range_blocks[block].base_msr + range,
488 &changed, (unsigned int *) saved++); 500 &changed, (unsigned int *)saved++);
501 }
489 502
490 return changed; 503 return changed;
491} 504}
492 505
493/* Set the MSR pair relating to a var range. Returns TRUE if 506/*
494 changes are made */ 507 * Set the MSR pair relating to a var range.
508 * Returns true if changes are made.
509 */
495static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) 510static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
496{ 511{
497 unsigned int lo, hi; 512 unsigned int lo, hi;
@@ -501,6 +516,7 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
501 if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL) 516 if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
502 || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != 517 || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
503 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { 518 (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
519
504 mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); 520 mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
505 changed = true; 521 changed = true;
506 } 522 }
@@ -526,21 +542,26 @@ static u32 deftype_lo, deftype_hi;
526 */ 542 */
527static unsigned long set_mtrr_state(void) 543static unsigned long set_mtrr_state(void)
528{ 544{
529 unsigned int i;
530 unsigned long change_mask = 0; 545 unsigned long change_mask = 0;
546 unsigned int i;
531 547
532 for (i = 0; i < num_var_ranges; i++) 548 for (i = 0; i < num_var_ranges; i++) {
533 if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) 549 if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i]))
534 change_mask |= MTRR_CHANGE_MASK_VARIABLE; 550 change_mask |= MTRR_CHANGE_MASK_VARIABLE;
551 }
535 552
536 if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) 553 if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges))
537 change_mask |= MTRR_CHANGE_MASK_FIXED; 554 change_mask |= MTRR_CHANGE_MASK_FIXED;
538 555
539 /* Set_mtrr_restore restores the old value of MTRRdefType, 556 /*
540 so to set it we fiddle with the saved value */ 557 * Set_mtrr_restore restores the old value of MTRRdefType,
558 * so to set it we fiddle with the saved value:
559 */
541 if ((deftype_lo & 0xff) != mtrr_state.def_type 560 if ((deftype_lo & 0xff) != mtrr_state.def_type
542 || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { 561 || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) {
543 deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | (mtrr_state.enabled << 10); 562
563 deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type |
564 (mtrr_state.enabled << 10);
544 change_mask |= MTRR_CHANGE_MASK_DEFTYPE; 565 change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
545 } 566 }
546 567
@@ -548,33 +569,36 @@ static unsigned long set_mtrr_state(void)
548} 569}
549 570
550 571
551static unsigned long cr4 = 0; 572static unsigned long cr4;
552static DEFINE_SPINLOCK(set_atomicity_lock); 573static DEFINE_SPINLOCK(set_atomicity_lock);
553 574
554/* 575/*
555 * Since we are disabling the cache don't allow any interrupts - they 576 * Since we are disabling the cache don't allow any interrupts,
556 * would run extremely slow and would only increase the pain. The caller must 577 * they would run extremely slow and would only increase the pain.
557 * ensure that local interrupts are disabled and are reenabled after post_set() 578 *
558 * has been called. 579 * The caller must ensure that local interrupts are disabled and
580 * are reenabled after post_set() has been called.
559 */ 581 */
560
561static void prepare_set(void) __acquires(set_atomicity_lock) 582static void prepare_set(void) __acquires(set_atomicity_lock)
562{ 583{
563 unsigned long cr0; 584 unsigned long cr0;
564 585
565 /* Note that this is not ideal, since the cache is only flushed/disabled 586 /*
566 for this CPU while the MTRRs are changed, but changing this requires 587 * Note that this is not ideal
567 more invasive changes to the way the kernel boots */ 588 * since the cache is only flushed/disabled for this CPU while the
589 * MTRRs are changed, but changing this requires more invasive
590 * changes to the way the kernel boots
591 */
568 592
569 spin_lock(&set_atomicity_lock); 593 spin_lock(&set_atomicity_lock);
570 594
571 /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ 595 /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
572 cr0 = read_cr0() | X86_CR0_CD; 596 cr0 = read_cr0() | X86_CR0_CD;
573 write_cr0(cr0); 597 write_cr0(cr0);
574 wbinvd(); 598 wbinvd();
575 599
576 /* Save value of CR4 and clear Page Global Enable (bit 7) */ 600 /* Save value of CR4 and clear Page Global Enable (bit 7) */
577 if ( cpu_has_pge ) { 601 if (cpu_has_pge) {
578 cr4 = read_cr4(); 602 cr4 = read_cr4();
579 write_cr4(cr4 & ~X86_CR4_PGE); 603 write_cr4(cr4 & ~X86_CR4_PGE);
580 } 604 }
@@ -582,26 +606,26 @@ static void prepare_set(void) __acquires(set_atomicity_lock)
582 /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ 606 /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
583 __flush_tlb(); 607 __flush_tlb();
584 608
585 /* Save MTRR state */ 609 /* Save MTRR state */
586 rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); 610 rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
587 611
588 /* Disable MTRRs, and set the default type to uncached */ 612 /* Disable MTRRs, and set the default type to uncached */
589 mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); 613 mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
590} 614}
591 615
592static void post_set(void) __releases(set_atomicity_lock) 616static void post_set(void) __releases(set_atomicity_lock)
593{ 617{
594 /* Flush TLBs (no need to flush caches - they are disabled) */ 618 /* Flush TLBs (no need to flush caches - they are disabled) */
595 __flush_tlb(); 619 __flush_tlb();
596 620
597 /* Intel (P6) standard MTRRs */ 621 /* Intel (P6) standard MTRRs */
598 mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); 622 mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
599 623
600 /* Enable caches */ 624 /* Enable caches */
601 write_cr0(read_cr0() & 0xbfffffff); 625 write_cr0(read_cr0() & 0xbfffffff);
602 626
603 /* Restore value of CR4 */ 627 /* Restore value of CR4 */
604 if ( cpu_has_pge ) 628 if (cpu_has_pge)
605 write_cr4(cr4); 629 write_cr4(cr4);
606 spin_unlock(&set_atomicity_lock); 630 spin_unlock(&set_atomicity_lock);
607} 631}
@@ -623,24 +647,27 @@ static void generic_set_all(void)
623 post_set(); 647 post_set();
624 local_irq_restore(flags); 648 local_irq_restore(flags);
625 649
626 /* Use the atomic bitops to update the global mask */ 650 /* Use the atomic bitops to update the global mask */
627 for (count = 0; count < sizeof mask * 8; ++count) { 651 for (count = 0; count < sizeof mask * 8; ++count) {
628 if (mask & 0x01) 652 if (mask & 0x01)
629 set_bit(count, &smp_changes_mask); 653 set_bit(count, &smp_changes_mask);
630 mask >>= 1; 654 mask >>= 1;
631 } 655 }
632 656
633} 657}
634 658
659/**
660 * generic_set_mtrr - set variable MTRR register on the local CPU.
661 *
662 * @reg: The register to set.
663 * @base: The base address of the region.
664 * @size: The size of the region. If this is 0 the region is disabled.
665 * @type: The type of the region.
666 *
667 * Returns nothing.
668 */
635static void generic_set_mtrr(unsigned int reg, unsigned long base, 669static void generic_set_mtrr(unsigned int reg, unsigned long base,
636 unsigned long size, mtrr_type type) 670 unsigned long size, mtrr_type type)
637/* [SUMMARY] Set variable MTRR register on the local CPU.
638 <reg> The register to set.
639 <base> The base address of the region.
640 <size> The size of the region. If this is 0 the region is disabled.
641 <type> The type of the region.
642 [RETURNS] Nothing.
643*/
644{ 671{
645 unsigned long flags; 672 unsigned long flags;
646 struct mtrr_var_range *vr; 673 struct mtrr_var_range *vr;
@@ -651,8 +678,10 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
651 prepare_set(); 678 prepare_set();
652 679
653 if (size == 0) { 680 if (size == 0) {
654 /* The invalid bit is kept in the mask, so we simply clear the 681 /*
655 relevant mask register to disable a range. */ 682 * The invalid bit is kept in the mask, so we simply
683 * clear the relevant mask register to disable a range.
684 */
656 mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0); 685 mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
657 memset(vr, 0, sizeof(struct mtrr_var_range)); 686 memset(vr, 0, sizeof(struct mtrr_var_range));
658 } else { 687 } else {
@@ -669,46 +698,50 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
669 local_irq_restore(flags); 698 local_irq_restore(flags);
670} 699}
671 700
672int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type) 701int generic_validate_add_page(unsigned long base, unsigned long size,
702 unsigned int type)
673{ 703{
674 unsigned long lbase, last; 704 unsigned long lbase, last;
675 705
676 /* For Intel PPro stepping <= 7, must be 4 MiB aligned 706 /*
677 and not touch 0x70000000->0x7003FFFF */ 707 * For Intel PPro stepping <= 7
708 * must be 4 MiB aligned and not touch 0x70000000 -> 0x7003FFFF
709 */
678 if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 && 710 if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 &&
679 boot_cpu_data.x86_model == 1 && 711 boot_cpu_data.x86_model == 1 &&
680 boot_cpu_data.x86_mask <= 7) { 712 boot_cpu_data.x86_mask <= 7) {
681 if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { 713 if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
682 printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); 714 pr_warning("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
683 return -EINVAL; 715 return -EINVAL;
684 } 716 }
685 if (!(base + size < 0x70000 || base > 0x7003F) && 717 if (!(base + size < 0x70000 || base > 0x7003F) &&
686 (type == MTRR_TYPE_WRCOMB 718 (type == MTRR_TYPE_WRCOMB
687 || type == MTRR_TYPE_WRBACK)) { 719 || type == MTRR_TYPE_WRBACK)) {
688 printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); 720 pr_warning("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
689 return -EINVAL; 721 return -EINVAL;
690 } 722 }
691 } 723 }
692 724
693 /* Check upper bits of base and last are equal and lower bits are 0 725 /*
694 for base and 1 for last */ 726 * Check upper bits of base and last are equal and lower bits are 0
727 * for base and 1 for last
728 */
695 last = base + size - 1; 729 last = base + size - 1;
696 for (lbase = base; !(lbase & 1) && (last & 1); 730 for (lbase = base; !(lbase & 1) && (last & 1);
697 lbase = lbase >> 1, last = last >> 1) ; 731 lbase = lbase >> 1, last = last >> 1)
732 ;
698 if (lbase != last) { 733 if (lbase != last) {
699 printk(KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", 734 pr_warning("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
700 base, size);
701 return -EINVAL; 735 return -EINVAL;
702 } 736 }
703 return 0; 737 return 0;
704} 738}
705 739
706
707static int generic_have_wrcomb(void) 740static int generic_have_wrcomb(void)
708{ 741{
709 unsigned long config, dummy; 742 unsigned long config, dummy;
710 rdmsr(MSR_MTRRcap, config, dummy); 743 rdmsr(MSR_MTRRcap, config, dummy);
711 return (config & (1 << 10)); 744 return config & (1 << 10);
712} 745}
713 746
714int positive_have_wrcomb(void) 747int positive_have_wrcomb(void)
@@ -716,14 +749,15 @@ int positive_have_wrcomb(void)
716 return 1; 749 return 1;
717} 750}
718 751
719/* generic structure... 752/*
753 * Generic structure...
720 */ 754 */
721struct mtrr_ops generic_mtrr_ops = { 755struct mtrr_ops generic_mtrr_ops = {
722 .use_intel_if = 1, 756 .use_intel_if = 1,
723 .set_all = generic_set_all, 757 .set_all = generic_set_all,
724 .get = generic_get_mtrr, 758 .get = generic_get_mtrr,
725 .get_free_region = generic_get_free_region, 759 .get_free_region = generic_get_free_region,
726 .set = generic_set_mtrr, 760 .set = generic_set_mtrr,
727 .validate_add_page = generic_validate_add_page, 761 .validate_add_page = generic_validate_add_page,
728 .have_wrcomb = generic_have_wrcomb, 762 .have_wrcomb = generic_have_wrcomb,
729}; 763};
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index fb73a52913a4..08b6ea4c62b4 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -1,27 +1,28 @@
1#include <linux/init.h>
2#include <linux/proc_fs.h>
3#include <linux/capability.h> 1#include <linux/capability.h>
4#include <linux/ctype.h>
5#include <linux/module.h>
6#include <linux/seq_file.h> 2#include <linux/seq_file.h>
7#include <asm/uaccess.h> 3#include <linux/uaccess.h>
4#include <linux/proc_fs.h>
5#include <linux/module.h>
6#include <linux/ctype.h>
7#include <linux/init.h>
8 8
9#define LINE_SIZE 80 9#define LINE_SIZE 80
10 10
11#include <asm/mtrr.h> 11#include <asm/mtrr.h>
12
12#include "mtrr.h" 13#include "mtrr.h"
13 14
14#define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) 15#define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private)
15 16
16static const char *const mtrr_strings[MTRR_NUM_TYPES] = 17static const char *const mtrr_strings[MTRR_NUM_TYPES] =
17{ 18{
18 "uncachable", /* 0 */ 19 "uncachable", /* 0 */
19 "write-combining", /* 1 */ 20 "write-combining", /* 1 */
20 "?", /* 2 */ 21 "?", /* 2 */
21 "?", /* 3 */ 22 "?", /* 3 */
22 "write-through", /* 4 */ 23 "write-through", /* 4 */
23 "write-protect", /* 5 */ 24 "write-protect", /* 5 */
24 "write-back", /* 6 */ 25 "write-back", /* 6 */
25}; 26};
26 27
27const char *mtrr_attrib_to_str(int x) 28const char *mtrr_attrib_to_str(int x)
@@ -35,8 +36,8 @@ static int
35mtrr_file_add(unsigned long base, unsigned long size, 36mtrr_file_add(unsigned long base, unsigned long size,
36 unsigned int type, bool increment, struct file *file, int page) 37 unsigned int type, bool increment, struct file *file, int page)
37{ 38{
39 unsigned int *fcount = FILE_FCOUNT(file);
38 int reg, max; 40 int reg, max;
39 unsigned int *fcount = FILE_FCOUNT(file);
40 41
41 max = num_var_ranges; 42 max = num_var_ranges;
42 if (fcount == NULL) { 43 if (fcount == NULL) {
@@ -61,8 +62,8 @@ static int
61mtrr_file_del(unsigned long base, unsigned long size, 62mtrr_file_del(unsigned long base, unsigned long size,
62 struct file *file, int page) 63 struct file *file, int page)
63{ 64{
64 int reg;
65 unsigned int *fcount = FILE_FCOUNT(file); 65 unsigned int *fcount = FILE_FCOUNT(file);
66 int reg;
66 67
67 if (!page) { 68 if (!page) {
68 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) 69 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)))
@@ -81,13 +82,14 @@ mtrr_file_del(unsigned long base, unsigned long size,
81 return reg; 82 return reg;
82} 83}
83 84
84/* RED-PEN: seq_file can seek now. this is ignored. */ 85/*
86 * seq_file can seek but we ignore it.
87 *
88 * Format of control line:
89 * "base=%Lx size=%Lx type=%s" or "disable=%d"
90 */
85static ssize_t 91static ssize_t
86mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) 92mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
87/* Format of control line:
88 "base=%Lx size=%Lx type=%s" OR:
89 "disable=%d"
90*/
91{ 93{
92 int i, err; 94 int i, err;
93 unsigned long reg; 95 unsigned long reg;
@@ -100,15 +102,18 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
100 return -EPERM; 102 return -EPERM;
101 if (!len) 103 if (!len)
102 return -EINVAL; 104 return -EINVAL;
105
103 memset(line, 0, LINE_SIZE); 106 memset(line, 0, LINE_SIZE);
104 if (len > LINE_SIZE) 107 if (len > LINE_SIZE)
105 len = LINE_SIZE; 108 len = LINE_SIZE;
106 if (copy_from_user(line, buf, len - 1)) 109 if (copy_from_user(line, buf, len - 1))
107 return -EFAULT; 110 return -EFAULT;
111
108 linelen = strlen(line); 112 linelen = strlen(line);
109 ptr = line + linelen - 1; 113 ptr = line + linelen - 1;
110 if (linelen && *ptr == '\n') 114 if (linelen && *ptr == '\n')
111 *ptr = '\0'; 115 *ptr = '\0';
116
112 if (!strncmp(line, "disable=", 8)) { 117 if (!strncmp(line, "disable=", 8)) {
113 reg = simple_strtoul(line + 8, &ptr, 0); 118 reg = simple_strtoul(line + 8, &ptr, 0);
114 err = mtrr_del_page(reg, 0, 0); 119 err = mtrr_del_page(reg, 0, 0);
@@ -116,28 +121,35 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
116 return err; 121 return err;
117 return len; 122 return len;
118 } 123 }
124
119 if (strncmp(line, "base=", 5)) 125 if (strncmp(line, "base=", 5))
120 return -EINVAL; 126 return -EINVAL;
127
121 base = simple_strtoull(line + 5, &ptr, 0); 128 base = simple_strtoull(line + 5, &ptr, 0);
122 for (; isspace(*ptr); ++ptr) ; 129 for (; isspace(*ptr); ++ptr)
130 ;
131
123 if (strncmp(ptr, "size=", 5)) 132 if (strncmp(ptr, "size=", 5))
124 return -EINVAL; 133 return -EINVAL;
134
125 size = simple_strtoull(ptr + 5, &ptr, 0); 135 size = simple_strtoull(ptr + 5, &ptr, 0);
126 if ((base & 0xfff) || (size & 0xfff)) 136 if ((base & 0xfff) || (size & 0xfff))
127 return -EINVAL; 137 return -EINVAL;
128 for (; isspace(*ptr); ++ptr) ; 138 for (; isspace(*ptr); ++ptr)
139 ;
140
129 if (strncmp(ptr, "type=", 5)) 141 if (strncmp(ptr, "type=", 5))
130 return -EINVAL; 142 return -EINVAL;
131 ptr += 5; 143 ptr += 5;
132 for (; isspace(*ptr); ++ptr) ; 144 for (; isspace(*ptr); ++ptr)
145 ;
146
133 for (i = 0; i < MTRR_NUM_TYPES; ++i) { 147 for (i = 0; i < MTRR_NUM_TYPES; ++i) {
134 if (strcmp(ptr, mtrr_strings[i])) 148 if (strcmp(ptr, mtrr_strings[i]))
135 continue; 149 continue;
136 base >>= PAGE_SHIFT; 150 base >>= PAGE_SHIFT;
137 size >>= PAGE_SHIFT; 151 size >>= PAGE_SHIFT;
138 err = 152 err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true);
139 mtrr_add_page((unsigned long) base, (unsigned long) size, i,
140 true);
141 if (err < 0) 153 if (err < 0)
142 return err; 154 return err;
143 return len; 155 return len;
@@ -181,7 +193,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
181 case MTRRIOC32_SET_PAGE_ENTRY: 193 case MTRRIOC32_SET_PAGE_ENTRY:
182 case MTRRIOC32_DEL_PAGE_ENTRY: 194 case MTRRIOC32_DEL_PAGE_ENTRY:
183 case MTRRIOC32_KILL_PAGE_ENTRY: { 195 case MTRRIOC32_KILL_PAGE_ENTRY: {
184 struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg; 196 struct mtrr_sentry32 __user *s32;
197
198 s32 = (struct mtrr_sentry32 __user *)__arg;
185 err = get_user(sentry.base, &s32->base); 199 err = get_user(sentry.base, &s32->base);
186 err |= get_user(sentry.size, &s32->size); 200 err |= get_user(sentry.size, &s32->size);
187 err |= get_user(sentry.type, &s32->type); 201 err |= get_user(sentry.type, &s32->type);
@@ -191,7 +205,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
191 } 205 }
192 case MTRRIOC32_GET_ENTRY: 206 case MTRRIOC32_GET_ENTRY:
193 case MTRRIOC32_GET_PAGE_ENTRY: { 207 case MTRRIOC32_GET_PAGE_ENTRY: {
194 struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg; 208 struct mtrr_gentry32 __user *g32;
209
210 g32 = (struct mtrr_gentry32 __user *)__arg;
195 err = get_user(gentry.regnum, &g32->regnum); 211 err = get_user(gentry.regnum, &g32->regnum);
196 err |= get_user(gentry.base, &g32->base); 212 err |= get_user(gentry.base, &g32->base);
197 err |= get_user(gentry.size, &g32->size); 213 err |= get_user(gentry.size, &g32->size);
@@ -314,7 +330,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
314 if (err) 330 if (err)
315 return err; 331 return err;
316 332
317 switch(cmd) { 333 switch (cmd) {
318 case MTRRIOC_GET_ENTRY: 334 case MTRRIOC_GET_ENTRY:
319 case MTRRIOC_GET_PAGE_ENTRY: 335 case MTRRIOC_GET_PAGE_ENTRY:
320 if (copy_to_user(arg, &gentry, sizeof gentry)) 336 if (copy_to_user(arg, &gentry, sizeof gentry))
@@ -323,7 +339,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
323#ifdef CONFIG_COMPAT 339#ifdef CONFIG_COMPAT
324 case MTRRIOC32_GET_ENTRY: 340 case MTRRIOC32_GET_ENTRY:
325 case MTRRIOC32_GET_PAGE_ENTRY: { 341 case MTRRIOC32_GET_PAGE_ENTRY: {
326 struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg; 342 struct mtrr_gentry32 __user *g32;
343
344 g32 = (struct mtrr_gentry32 __user *)__arg;
327 err = put_user(gentry.base, &g32->base); 345 err = put_user(gentry.base, &g32->base);
328 err |= put_user(gentry.size, &g32->size); 346 err |= put_user(gentry.size, &g32->size);
329 err |= put_user(gentry.regnum, &g32->regnum); 347 err |= put_user(gentry.regnum, &g32->regnum);
@@ -335,11 +353,10 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
335 return err; 353 return err;
336} 354}
337 355
338static int 356static int mtrr_close(struct inode *ino, struct file *file)
339mtrr_close(struct inode *ino, struct file *file)
340{ 357{
341 int i, max;
342 unsigned int *fcount = FILE_FCOUNT(file); 358 unsigned int *fcount = FILE_FCOUNT(file);
359 int i, max;
343 360
344 if (fcount != NULL) { 361 if (fcount != NULL) {
345 max = num_var_ranges; 362 max = num_var_ranges;
@@ -359,22 +376,22 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset);
359 376
360static int mtrr_open(struct inode *inode, struct file *file) 377static int mtrr_open(struct inode *inode, struct file *file)
361{ 378{
362 if (!mtrr_if) 379 if (!mtrr_if)
363 return -EIO; 380 return -EIO;
364 if (!mtrr_if->get) 381 if (!mtrr_if->get)
365 return -ENXIO; 382 return -ENXIO;
366 return single_open(file, mtrr_seq_show, NULL); 383 return single_open(file, mtrr_seq_show, NULL);
367} 384}
368 385
369static const struct file_operations mtrr_fops = { 386static const struct file_operations mtrr_fops = {
370 .owner = THIS_MODULE, 387 .owner = THIS_MODULE,
371 .open = mtrr_open, 388 .open = mtrr_open,
372 .read = seq_read, 389 .read = seq_read,
373 .llseek = seq_lseek, 390 .llseek = seq_lseek,
374 .write = mtrr_write, 391 .write = mtrr_write,
375 .unlocked_ioctl = mtrr_ioctl, 392 .unlocked_ioctl = mtrr_ioctl,
376 .compat_ioctl = mtrr_ioctl, 393 .compat_ioctl = mtrr_ioctl,
377 .release = mtrr_close, 394 .release = mtrr_close,
378}; 395};
379 396
380static int mtrr_seq_show(struct seq_file *seq, void *offset) 397static int mtrr_seq_show(struct seq_file *seq, void *offset)
@@ -388,23 +405,24 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
388 max = num_var_ranges; 405 max = num_var_ranges;
389 for (i = 0; i < max; i++) { 406 for (i = 0; i < max; i++) {
390 mtrr_if->get(i, &base, &size, &type); 407 mtrr_if->get(i, &base, &size, &type);
391 if (size == 0) 408 if (size == 0) {
392 mtrr_usage_table[i] = 0; 409 mtrr_usage_table[i] = 0;
393 else { 410 continue;
394 if (size < (0x100000 >> PAGE_SHIFT)) {
395 /* less than 1MB */
396 factor = 'K';
397 size <<= PAGE_SHIFT - 10;
398 } else {
399 factor = 'M';
400 size >>= 20 - PAGE_SHIFT;
401 }
402 /* RED-PEN: base can be > 32bit */
403 len += seq_printf(seq,
404 "reg%02i: base=0x%06lx000 (%5luMB), size=%5lu%cB, count=%d: %s\n",
405 i, base, base >> (20 - PAGE_SHIFT), size, factor,
406 mtrr_usage_table[i], mtrr_attrib_to_str(type));
407 } 411 }
412 if (size < (0x100000 >> PAGE_SHIFT)) {
413 /* less than 1MB */
414 factor = 'K';
415 size <<= PAGE_SHIFT - 10;
416 } else {
417 factor = 'M';
418 size >>= 20 - PAGE_SHIFT;
419 }
420 /* Base can be > 32bit */
421 len += seq_printf(seq, "reg%02i: base=0x%06lx000 "
422 "(%5luMB), size=%5lu%cB, count=%d: %s\n",
423 i, base, base >> (20 - PAGE_SHIFT), size,
424 factor, mtrr_usage_table[i],
425 mtrr_attrib_to_str(type));
408 } 426 }
409 return 0; 427 return 0;
410} 428}
@@ -422,6 +440,5 @@ static int __init mtrr_if_init(void)
422 proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); 440 proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
423 return 0; 441 return 0;
424} 442}
425
426arch_initcall(mtrr_if_init); 443arch_initcall(mtrr_if_init);
427#endif /* CONFIG_PROC_FS */ 444#endif /* CONFIG_PROC_FS */
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 8fc248b5aeaf..7af0f88a4163 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -25,43 +25,48 @@
25 Operating System Writer's Guide" (Intel document number 242692), 25 Operating System Writer's Guide" (Intel document number 242692),
26 section 11.11.7 26 section 11.11.7
27 27
28 This was cleaned and made readable by Patrick Mochel <mochel@osdl.org> 28 This was cleaned and made readable by Patrick Mochel <mochel@osdl.org>
29 on 6-7 March 2002. 29 on 6-7 March 2002.
30 Source: Intel Architecture Software Developers Manual, Volume 3: 30 Source: Intel Architecture Software Developers Manual, Volume 3:
31 System Programming Guide; Section 9.11. (1997 edition - PPro). 31 System Programming Guide; Section 9.11. (1997 edition - PPro).
32*/ 32*/
33 33
34#define DEBUG
35
36#include <linux/types.h> /* FIXME: kvm_para.h needs this */
37
38#include <linux/kvm_para.h>
39#include <linux/uaccess.h>
34#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/mutex.h>
35#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/sort.h>
44#include <linux/cpu.h>
36#include <linux/pci.h> 45#include <linux/pci.h>
37#include <linux/smp.h> 46#include <linux/smp.h>
38#include <linux/cpu.h>
39#include <linux/mutex.h>
40#include <linux/sort.h>
41 47
48#include <asm/processor.h>
42#include <asm/e820.h> 49#include <asm/e820.h>
43#include <asm/mtrr.h> 50#include <asm/mtrr.h>
44#include <asm/uaccess.h>
45#include <asm/processor.h>
46#include <asm/msr.h> 51#include <asm/msr.h>
47#include <asm/kvm_para.h> 52
48#include "mtrr.h" 53#include "mtrr.h"
49 54
50u32 num_var_ranges = 0; 55u32 num_var_ranges;
51 56
52unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; 57unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
53static DEFINE_MUTEX(mtrr_mutex); 58static DEFINE_MUTEX(mtrr_mutex);
54 59
55u64 size_or_mask, size_and_mask; 60u64 size_or_mask, size_and_mask;
56 61
57static struct mtrr_ops * mtrr_ops[X86_VENDOR_NUM] = {}; 62static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
58 63
59struct mtrr_ops * mtrr_if = NULL; 64struct mtrr_ops *mtrr_if;
60 65
61static void set_mtrr(unsigned int reg, unsigned long base, 66static void set_mtrr(unsigned int reg, unsigned long base,
62 unsigned long size, mtrr_type type); 67 unsigned long size, mtrr_type type);
63 68
64void set_mtrr_ops(struct mtrr_ops * ops) 69void set_mtrr_ops(struct mtrr_ops *ops)
65{ 70{
66 if (ops->vendor && ops->vendor < X86_VENDOR_NUM) 71 if (ops->vendor && ops->vendor < X86_VENDOR_NUM)
67 mtrr_ops[ops->vendor] = ops; 72 mtrr_ops[ops->vendor] = ops;
@@ -72,30 +77,36 @@ static int have_wrcomb(void)
72{ 77{
73 struct pci_dev *dev; 78 struct pci_dev *dev;
74 u8 rev; 79 u8 rev;
75 80
76 if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { 81 dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL);
77 /* ServerWorks LE chipsets < rev 6 have problems with write-combining 82 if (dev != NULL) {
78 Don't allow it and leave room for other chipsets to be tagged */ 83 /*
84 * ServerWorks LE chipsets < rev 6 have problems with
85 * write-combining. Don't allow it and leave room for other
86 * chipsets to be tagged
87 */
79 if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && 88 if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
80 dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { 89 dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
81 pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); 90 pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
82 if (rev <= 5) { 91 if (rev <= 5) {
83 printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n"); 92 pr_info("mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
84 pci_dev_put(dev); 93 pci_dev_put(dev);
85 return 0; 94 return 0;
86 } 95 }
87 } 96 }
88 /* Intel 450NX errata # 23. Non ascending cacheline evictions to 97 /*
89 write combining memory may resulting in data corruption */ 98 * Intel 450NX errata # 23. Non ascending cacheline evictions to
99 * write combining memory may resulting in data corruption
100 */
90 if (dev->vendor == PCI_VENDOR_ID_INTEL && 101 if (dev->vendor == PCI_VENDOR_ID_INTEL &&
91 dev->device == PCI_DEVICE_ID_INTEL_82451NX) { 102 dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
92 printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n"); 103 pr_info("mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
93 pci_dev_put(dev); 104 pci_dev_put(dev);
94 return 0; 105 return 0;
95 } 106 }
96 pci_dev_put(dev); 107 pci_dev_put(dev);
97 } 108 }
98 return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0); 109 return mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0;
99} 110}
100 111
101/* This function returns the number of variable MTRRs */ 112/* This function returns the number of variable MTRRs */
@@ -103,12 +114,13 @@ static void __init set_num_var_ranges(void)
103{ 114{
104 unsigned long config = 0, dummy; 115 unsigned long config = 0, dummy;
105 116
106 if (use_intel()) { 117 if (use_intel())
107 rdmsr(MSR_MTRRcap, config, dummy); 118 rdmsr(MSR_MTRRcap, config, dummy);
108 } else if (is_cpu(AMD)) 119 else if (is_cpu(AMD))
109 config = 2; 120 config = 2;
110 else if (is_cpu(CYRIX) || is_cpu(CENTAUR)) 121 else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
111 config = 8; 122 config = 8;
123
112 num_var_ranges = config & 0xff; 124 num_var_ranges = config & 0xff;
113} 125}
114 126
@@ -130,10 +142,12 @@ struct set_mtrr_data {
130 mtrr_type smp_type; 142 mtrr_type smp_type;
131}; 143};
132 144
145/**
146 * ipi_handler - Synchronisation handler. Executed by "other" CPUs.
147 *
148 * Returns nothing.
149 */
133static void ipi_handler(void *info) 150static void ipi_handler(void *info)
134/* [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
135 [RETURNS] Nothing.
136*/
137{ 151{
138#ifdef CONFIG_SMP 152#ifdef CONFIG_SMP
139 struct set_mtrr_data *data = info; 153 struct set_mtrr_data *data = info;
@@ -142,18 +156,19 @@ static void ipi_handler(void *info)
142 local_irq_save(flags); 156 local_irq_save(flags);
143 157
144 atomic_dec(&data->count); 158 atomic_dec(&data->count);
145 while(!atomic_read(&data->gate)) 159 while (!atomic_read(&data->gate))
146 cpu_relax(); 160 cpu_relax();
147 161
148 /* The master has cleared me to execute */ 162 /* The master has cleared me to execute */
149 if (data->smp_reg != ~0U) 163 if (data->smp_reg != ~0U) {
150 mtrr_if->set(data->smp_reg, data->smp_base, 164 mtrr_if->set(data->smp_reg, data->smp_base,
151 data->smp_size, data->smp_type); 165 data->smp_size, data->smp_type);
152 else 166 } else {
153 mtrr_if->set_all(); 167 mtrr_if->set_all();
168 }
154 169
155 atomic_dec(&data->count); 170 atomic_dec(&data->count);
156 while(atomic_read(&data->gate)) 171 while (atomic_read(&data->gate))
157 cpu_relax(); 172 cpu_relax();
158 173
159 atomic_dec(&data->count); 174 atomic_dec(&data->count);
@@ -161,7 +176,8 @@ static void ipi_handler(void *info)
161#endif 176#endif
162} 177}
163 178
164static inline int types_compatible(mtrr_type type1, mtrr_type type2) { 179static inline int types_compatible(mtrr_type type1, mtrr_type type2)
180{
165 return type1 == MTRR_TYPE_UNCACHABLE || 181 return type1 == MTRR_TYPE_UNCACHABLE ||
166 type2 == MTRR_TYPE_UNCACHABLE || 182 type2 == MTRR_TYPE_UNCACHABLE ||
167 (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) || 183 (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) ||
@@ -176,10 +192,10 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
176 * @type: mtrr type 192 * @type: mtrr type
177 * 193 *
178 * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly: 194 * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly:
179 * 195 *
180 * 1. Send IPI to do the following: 196 * 1. Send IPI to do the following:
181 * 2. Disable Interrupts 197 * 2. Disable Interrupts
182 * 3. Wait for all procs to do so 198 * 3. Wait for all procs to do so
183 * 4. Enter no-fill cache mode 199 * 4. Enter no-fill cache mode
184 * 5. Flush caches 200 * 5. Flush caches
185 * 6. Clear PGE bit 201 * 6. Clear PGE bit
@@ -189,26 +205,27 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
189 * 10. Enable all range registers 205 * 10. Enable all range registers
190 * 11. Flush all TLBs and caches again 206 * 11. Flush all TLBs and caches again
191 * 12. Enter normal cache mode and reenable caching 207 * 12. Enter normal cache mode and reenable caching
192 * 13. Set PGE 208 * 13. Set PGE
193 * 14. Wait for buddies to catch up 209 * 14. Wait for buddies to catch up
194 * 15. Enable interrupts. 210 * 15. Enable interrupts.
195 * 211 *
196 * What does that mean for us? Well, first we set data.count to the number 212 * What does that mean for us? Well, first we set data.count to the number
197 * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait 213 * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait
198 * until it hits 0 and proceed. We set the data.gate flag and reset data.count. 214 * until it hits 0 and proceed. We set the data.gate flag and reset data.count.
199 * Meanwhile, they are waiting for that flag to be set. Once it's set, each 215 * Meanwhile, they are waiting for that flag to be set. Once it's set, each
200 * CPU goes through the transition of updating MTRRs. The CPU vendors may each do it 216 * CPU goes through the transition of updating MTRRs.
201 * differently, so we call mtrr_if->set() callback and let them take care of it. 217 * The CPU vendors may each do it differently,
202 * When they're done, they again decrement data->count and wait for data.gate to 218 * so we call mtrr_if->set() callback and let them take care of it.
203 * be reset. 219 * When they're done, they again decrement data->count and wait for data.gate
204 * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag. 220 * to be reset.
221 * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag
205 * Everyone then enables interrupts and we all continue on. 222 * Everyone then enables interrupts and we all continue on.
206 * 223 *
207 * Note that the mechanism is the same for UP systems, too; all the SMP stuff 224 * Note that the mechanism is the same for UP systems, too; all the SMP stuff
208 * becomes nops. 225 * becomes nops.
209 */ 226 */
210static void set_mtrr(unsigned int reg, unsigned long base, 227static void
211 unsigned long size, mtrr_type type) 228set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
212{ 229{
213 struct set_mtrr_data data; 230 struct set_mtrr_data data;
214 unsigned long flags; 231 unsigned long flags;
@@ -218,121 +235,122 @@ static void set_mtrr(unsigned int reg, unsigned long base,
218 data.smp_size = size; 235 data.smp_size = size;
219 data.smp_type = type; 236 data.smp_type = type;
220 atomic_set(&data.count, num_booting_cpus() - 1); 237 atomic_set(&data.count, num_booting_cpus() - 1);
221 /* make sure data.count is visible before unleashing other CPUs */ 238
239 /* Make sure data.count is visible before unleashing other CPUs */
222 smp_wmb(); 240 smp_wmb();
223 atomic_set(&data.gate,0); 241 atomic_set(&data.gate, 0);
224 242
225 /* Start the ball rolling on other CPUs */ 243 /* Start the ball rolling on other CPUs */
226 if (smp_call_function(ipi_handler, &data, 0) != 0) 244 if (smp_call_function(ipi_handler, &data, 0) != 0)
227 panic("mtrr: timed out waiting for other CPUs\n"); 245 panic("mtrr: timed out waiting for other CPUs\n");
228 246
229 local_irq_save(flags); 247 local_irq_save(flags);
230 248
231 while(atomic_read(&data.count)) 249 while (atomic_read(&data.count))
232 cpu_relax(); 250 cpu_relax();
233 251
234 /* ok, reset count and toggle gate */ 252 /* Ok, reset count and toggle gate */
235 atomic_set(&data.count, num_booting_cpus() - 1); 253 atomic_set(&data.count, num_booting_cpus() - 1);
236 smp_wmb(); 254 smp_wmb();
237 atomic_set(&data.gate,1); 255 atomic_set(&data.gate, 1);
238 256
239 /* do our MTRR business */ 257 /* Do our MTRR business */
240 258
241 /* HACK! 259 /*
260 * HACK!
242 * We use this same function to initialize the mtrrs on boot. 261 * We use this same function to initialize the mtrrs on boot.
243 * The state of the boot cpu's mtrrs has been saved, and we want 262 * The state of the boot cpu's mtrrs has been saved, and we want
244 * to replicate across all the APs. 263 * to replicate across all the APs.
245 * If we're doing that @reg is set to something special... 264 * If we're doing that @reg is set to something special...
246 */ 265 */
247 if (reg != ~0U) 266 if (reg != ~0U)
248 mtrr_if->set(reg,base,size,type); 267 mtrr_if->set(reg, base, size, type);
249 268
250 /* wait for the others */ 269 /* Wait for the others */
251 while(atomic_read(&data.count)) 270 while (atomic_read(&data.count))
252 cpu_relax(); 271 cpu_relax();
253 272
254 atomic_set(&data.count, num_booting_cpus() - 1); 273 atomic_set(&data.count, num_booting_cpus() - 1);
255 smp_wmb(); 274 smp_wmb();
256 atomic_set(&data.gate,0); 275 atomic_set(&data.gate, 0);
257 276
258 /* 277 /*
259 * Wait here for everyone to have seen the gate change 278 * Wait here for everyone to have seen the gate change
260 * So we're the last ones to touch 'data' 279 * So we're the last ones to touch 'data'
261 */ 280 */
262 while(atomic_read(&data.count)) 281 while (atomic_read(&data.count))
263 cpu_relax(); 282 cpu_relax();
264 283
265 local_irq_restore(flags); 284 local_irq_restore(flags);
266} 285}
267 286
268/** 287/**
269 * mtrr_add_page - Add a memory type region 288 * mtrr_add_page - Add a memory type region
270 * @base: Physical base address of region in pages (in units of 4 kB!) 289 * @base: Physical base address of region in pages (in units of 4 kB!)
271 * @size: Physical size of region in pages (4 kB) 290 * @size: Physical size of region in pages (4 kB)
272 * @type: Type of MTRR desired 291 * @type: Type of MTRR desired
273 * @increment: If this is true do usage counting on the region 292 * @increment: If this is true do usage counting on the region
274 * 293 *
275 * Memory type region registers control the caching on newer Intel and 294 * Memory type region registers control the caching on newer Intel and
276 * non Intel processors. This function allows drivers to request an 295 * non Intel processors. This function allows drivers to request an
277 * MTRR is added. The details and hardware specifics of each processor's 296 * MTRR is added. The details and hardware specifics of each processor's
278 * implementation are hidden from the caller, but nevertheless the 297 * implementation are hidden from the caller, but nevertheless the
279 * caller should expect to need to provide a power of two size on an 298 * caller should expect to need to provide a power of two size on an
280 * equivalent power of two boundary. 299 * equivalent power of two boundary.
281 * 300 *
282 * If the region cannot be added either because all regions are in use 301 * If the region cannot be added either because all regions are in use
283 * or the CPU cannot support it a negative value is returned. On success 302 * or the CPU cannot support it a negative value is returned. On success
284 * the register number for this entry is returned, but should be treated 303 * the register number for this entry is returned, but should be treated
285 * as a cookie only. 304 * as a cookie only.
286 * 305 *
287 * On a multiprocessor machine the changes are made to all processors. 306 * On a multiprocessor machine the changes are made to all processors.
288 * This is required on x86 by the Intel processors. 307 * This is required on x86 by the Intel processors.
289 * 308 *
290 * The available types are 309 * The available types are
291 * 310 *
292 * %MTRR_TYPE_UNCACHABLE - No caching 311 * %MTRR_TYPE_UNCACHABLE - No caching
293 * 312 *
294 * %MTRR_TYPE_WRBACK - Write data back in bursts whenever 313 * %MTRR_TYPE_WRBACK - Write data back in bursts whenever
295 * 314 *
296 * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts 315 * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
297 * 316 *
298 * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes 317 * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
299 * 318 *
300 * BUGS: Needs a quiet flag for the cases where drivers do not mind 319 * BUGS: Needs a quiet flag for the cases where drivers do not mind
301 * failures and do not wish system log messages to be sent. 320 * failures and do not wish system log messages to be sent.
302 */ 321 */
303 322int mtrr_add_page(unsigned long base, unsigned long size,
304int mtrr_add_page(unsigned long base, unsigned long size,
305 unsigned int type, bool increment) 323 unsigned int type, bool increment)
306{ 324{
325 unsigned long lbase, lsize;
307 int i, replace, error; 326 int i, replace, error;
308 mtrr_type ltype; 327 mtrr_type ltype;
309 unsigned long lbase, lsize;
310 328
311 if (!mtrr_if) 329 if (!mtrr_if)
312 return -ENXIO; 330 return -ENXIO;
313 331
314 if ((error = mtrr_if->validate_add_page(base,size,type))) 332 error = mtrr_if->validate_add_page(base, size, type);
333 if (error)
315 return error; 334 return error;
316 335
317 if (type >= MTRR_NUM_TYPES) { 336 if (type >= MTRR_NUM_TYPES) {
318 printk(KERN_WARNING "mtrr: type: %u invalid\n", type); 337 pr_warning("mtrr: type: %u invalid\n", type);
319 return -EINVAL; 338 return -EINVAL;
320 } 339 }
321 340
322 /* If the type is WC, check that this processor supports it */ 341 /* If the type is WC, check that this processor supports it */
323 if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) { 342 if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
324 printk(KERN_WARNING 343 pr_warning("mtrr: your processor doesn't support write-combining\n");
325 "mtrr: your processor doesn't support write-combining\n");
326 return -ENOSYS; 344 return -ENOSYS;
327 } 345 }
328 346
329 if (!size) { 347 if (!size) {
330 printk(KERN_WARNING "mtrr: zero sized request\n"); 348 pr_warning("mtrr: zero sized request\n");
331 return -EINVAL; 349 return -EINVAL;
332 } 350 }
333 351
334 if (base & size_or_mask || size & size_or_mask) { 352 if (base & size_or_mask || size & size_or_mask) {
335 printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n"); 353 pr_warning("mtrr: base or size exceeds the MTRR width\n");
336 return -EINVAL; 354 return -EINVAL;
337 } 355 }
338 356
@@ -341,36 +359,40 @@ int mtrr_add_page(unsigned long base, unsigned long size,
341 359
342 /* No CPU hotplug when we change MTRR entries */ 360 /* No CPU hotplug when we change MTRR entries */
343 get_online_cpus(); 361 get_online_cpus();
344 /* Search for existing MTRR */ 362
363 /* Search for existing MTRR */
345 mutex_lock(&mtrr_mutex); 364 mutex_lock(&mtrr_mutex);
346 for (i = 0; i < num_var_ranges; ++i) { 365 for (i = 0; i < num_var_ranges; ++i) {
347 mtrr_if->get(i, &lbase, &lsize, &ltype); 366 mtrr_if->get(i, &lbase, &lsize, &ltype);
348 if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase) 367 if (!lsize || base > lbase + lsize - 1 ||
368 base + size - 1 < lbase)
349 continue; 369 continue;
350 /* At this point we know there is some kind of overlap/enclosure */ 370 /*
371 * At this point we know there is some kind of
372 * overlap/enclosure
373 */
351 if (base < lbase || base + size - 1 > lbase + lsize - 1) { 374 if (base < lbase || base + size - 1 > lbase + lsize - 1) {
352 if (base <= lbase && base + size - 1 >= lbase + lsize - 1) { 375 if (base <= lbase &&
376 base + size - 1 >= lbase + lsize - 1) {
353 /* New region encloses an existing region */ 377 /* New region encloses an existing region */
354 if (type == ltype) { 378 if (type == ltype) {
355 replace = replace == -1 ? i : -2; 379 replace = replace == -1 ? i : -2;
356 continue; 380 continue;
357 } 381 } else if (types_compatible(type, ltype))
358 else if (types_compatible(type, ltype))
359 continue; 382 continue;
360 } 383 }
361 printk(KERN_WARNING 384 pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing"
362 "mtrr: 0x%lx000,0x%lx000 overlaps existing" 385 " 0x%lx000,0x%lx000\n", base, size, lbase,
363 " 0x%lx000,0x%lx000\n", base, size, lbase, 386 lsize);
364 lsize);
365 goto out; 387 goto out;
366 } 388 }
367 /* New region is enclosed by an existing region */ 389 /* New region is enclosed by an existing region */
368 if (ltype != type) { 390 if (ltype != type) {
369 if (types_compatible(type, ltype)) 391 if (types_compatible(type, ltype))
370 continue; 392 continue;
371 printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", 393 pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
372 base, size, mtrr_attrib_to_str(ltype), 394 base, size, mtrr_attrib_to_str(ltype),
373 mtrr_attrib_to_str(type)); 395 mtrr_attrib_to_str(type));
374 goto out; 396 goto out;
375 } 397 }
376 if (increment) 398 if (increment)
@@ -378,7 +400,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
378 error = i; 400 error = i;
379 goto out; 401 goto out;
380 } 402 }
381 /* Search for an empty MTRR */ 403 /* Search for an empty MTRR */
382 i = mtrr_if->get_free_region(base, size, replace); 404 i = mtrr_if->get_free_region(base, size, replace);
383 if (i >= 0) { 405 if (i >= 0) {
384 set_mtrr(i, base, size, type); 406 set_mtrr(i, base, size, type);
@@ -393,8 +415,9 @@ int mtrr_add_page(unsigned long base, unsigned long size,
393 mtrr_usage_table[replace] = 0; 415 mtrr_usage_table[replace] = 0;
394 } 416 }
395 } 417 }
396 } else 418 } else {
397 printk(KERN_INFO "mtrr: no more MTRRs available\n"); 419 pr_info("mtrr: no more MTRRs available\n");
420 }
398 error = i; 421 error = i;
399 out: 422 out:
400 mutex_unlock(&mtrr_mutex); 423 mutex_unlock(&mtrr_mutex);
@@ -405,10 +428,8 @@ int mtrr_add_page(unsigned long base, unsigned long size,
405static int mtrr_check(unsigned long base, unsigned long size) 428static int mtrr_check(unsigned long base, unsigned long size)
406{ 429{
407 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { 430 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
408 printk(KERN_WARNING 431 pr_warning("mtrr: size and base must be multiples of 4 kiB\n");
409 "mtrr: size and base must be multiples of 4 kiB\n"); 432 pr_debug("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
410 printk(KERN_DEBUG
411 "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
412 dump_stack(); 433 dump_stack();
413 return -1; 434 return -1;
414 } 435 }
@@ -416,66 +437,64 @@ static int mtrr_check(unsigned long base, unsigned long size)
416} 437}
417 438
418/** 439/**
419 * mtrr_add - Add a memory type region 440 * mtrr_add - Add a memory type region
420 * @base: Physical base address of region 441 * @base: Physical base address of region
421 * @size: Physical size of region 442 * @size: Physical size of region
422 * @type: Type of MTRR desired 443 * @type: Type of MTRR desired
423 * @increment: If this is true do usage counting on the region 444 * @increment: If this is true do usage counting on the region
424 * 445 *
425 * Memory type region registers control the caching on newer Intel and 446 * Memory type region registers control the caching on newer Intel and
426 * non Intel processors. This function allows drivers to request an 447 * non Intel processors. This function allows drivers to request an
427 * MTRR is added. The details and hardware specifics of each processor's 448 * MTRR is added. The details and hardware specifics of each processor's
428 * implementation are hidden from the caller, but nevertheless the 449 * implementation are hidden from the caller, but nevertheless the
429 * caller should expect to need to provide a power of two size on an 450 * caller should expect to need to provide a power of two size on an
430 * equivalent power of two boundary. 451 * equivalent power of two boundary.
431 * 452 *
432 * If the region cannot be added either because all regions are in use 453 * If the region cannot be added either because all regions are in use
433 * or the CPU cannot support it a negative value is returned. On success 454 * or the CPU cannot support it a negative value is returned. On success
434 * the register number for this entry is returned, but should be treated 455 * the register number for this entry is returned, but should be treated
435 * as a cookie only. 456 * as a cookie only.
436 * 457 *
437 * On a multiprocessor machine the changes are made to all processors. 458 * On a multiprocessor machine the changes are made to all processors.
438 * This is required on x86 by the Intel processors. 459 * This is required on x86 by the Intel processors.
439 * 460 *
440 * The available types are 461 * The available types are
441 * 462 *
442 * %MTRR_TYPE_UNCACHABLE - No caching 463 * %MTRR_TYPE_UNCACHABLE - No caching
443 * 464 *
444 * %MTRR_TYPE_WRBACK - Write data back in bursts whenever 465 * %MTRR_TYPE_WRBACK - Write data back in bursts whenever
445 * 466 *
446 * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts 467 * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
447 * 468 *
448 * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes 469 * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
449 * 470 *
450 * BUGS: Needs a quiet flag for the cases where drivers do not mind 471 * BUGS: Needs a quiet flag for the cases where drivers do not mind
451 * failures and do not wish system log messages to be sent. 472 * failures and do not wish system log messages to be sent.
452 */ 473 */
453 474int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
454int 475 bool increment)
455mtrr_add(unsigned long base, unsigned long size, unsigned int type,
456 bool increment)
457{ 476{
458 if (mtrr_check(base, size)) 477 if (mtrr_check(base, size))
459 return -EINVAL; 478 return -EINVAL;
460 return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, 479 return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
461 increment); 480 increment);
462} 481}
482EXPORT_SYMBOL(mtrr_add);
463 483
464/** 484/**
465 * mtrr_del_page - delete a memory type region 485 * mtrr_del_page - delete a memory type region
466 * @reg: Register returned by mtrr_add 486 * @reg: Register returned by mtrr_add
467 * @base: Physical base address 487 * @base: Physical base address
468 * @size: Size of region 488 * @size: Size of region
469 * 489 *
470 * If register is supplied then base and size are ignored. This is 490 * If register is supplied then base and size are ignored. This is
471 * how drivers should call it. 491 * how drivers should call it.
472 * 492 *
473 * Releases an MTRR region. If the usage count drops to zero the 493 * Releases an MTRR region. If the usage count drops to zero the
474 * register is freed and the region returns to default state. 494 * register is freed and the region returns to default state.
475 * On success the register is returned, on failure a negative error 495 * On success the register is returned, on failure a negative error
476 * code. 496 * code.
477 */ 497 */
478
479int mtrr_del_page(int reg, unsigned long base, unsigned long size) 498int mtrr_del_page(int reg, unsigned long base, unsigned long size)
480{ 499{
481 int i, max; 500 int i, max;
@@ -500,22 +519,22 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
500 } 519 }
501 } 520 }
502 if (reg < 0) { 521 if (reg < 0) {
503 printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base, 522 pr_debug("mtrr: no MTRR for %lx000,%lx000 found\n",
504 size); 523 base, size);
505 goto out; 524 goto out;
506 } 525 }
507 } 526 }
508 if (reg >= max) { 527 if (reg >= max) {
509 printk(KERN_WARNING "mtrr: register: %d too big\n", reg); 528 pr_warning("mtrr: register: %d too big\n", reg);
510 goto out; 529 goto out;
511 } 530 }
512 mtrr_if->get(reg, &lbase, &lsize, &ltype); 531 mtrr_if->get(reg, &lbase, &lsize, &ltype);
513 if (lsize < 1) { 532 if (lsize < 1) {
514 printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg); 533 pr_warning("mtrr: MTRR %d not used\n", reg);
515 goto out; 534 goto out;
516 } 535 }
517 if (mtrr_usage_table[reg] < 1) { 536 if (mtrr_usage_table[reg] < 1) {
518 printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg); 537 pr_warning("mtrr: reg: %d has count=0\n", reg);
519 goto out; 538 goto out;
520 } 539 }
521 if (--mtrr_usage_table[reg] < 1) 540 if (--mtrr_usage_table[reg] < 1)
@@ -526,33 +545,31 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
526 put_online_cpus(); 545 put_online_cpus();
527 return error; 546 return error;
528} 547}
548
529/** 549/**
530 * mtrr_del - delete a memory type region 550 * mtrr_del - delete a memory type region
531 * @reg: Register returned by mtrr_add 551 * @reg: Register returned by mtrr_add
532 * @base: Physical base address 552 * @base: Physical base address
533 * @size: Size of region 553 * @size: Size of region
534 * 554 *
535 * If register is supplied then base and size are ignored. This is 555 * If register is supplied then base and size are ignored. This is
536 * how drivers should call it. 556 * how drivers should call it.
537 * 557 *
538 * Releases an MTRR region. If the usage count drops to zero the 558 * Releases an MTRR region. If the usage count drops to zero the
539 * register is freed and the region returns to default state. 559 * register is freed and the region returns to default state.
540 * On success the register is returned, on failure a negative error 560 * On success the register is returned, on failure a negative error
541 * code. 561 * code.
542 */ 562 */
543 563int mtrr_del(int reg, unsigned long base, unsigned long size)
544int
545mtrr_del(int reg, unsigned long base, unsigned long size)
546{ 564{
547 if (mtrr_check(base, size)) 565 if (mtrr_check(base, size))
548 return -EINVAL; 566 return -EINVAL;
549 return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); 567 return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
550} 568}
551
552EXPORT_SYMBOL(mtrr_add);
553EXPORT_SYMBOL(mtrr_del); 569EXPORT_SYMBOL(mtrr_del);
554 570
555/* HACK ALERT! 571/*
572 * HACK ALERT!
556 * These should be called implicitly, but we can't yet until all the initcall 573 * These should be called implicitly, but we can't yet until all the initcall
557 * stuff is done... 574 * stuff is done...
558 */ 575 */
@@ -576,29 +593,28 @@ struct mtrr_value {
576 593
577static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; 594static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
578 595
579static int mtrr_save(struct sys_device * sysdev, pm_message_t state) 596static int mtrr_save(struct sys_device *sysdev, pm_message_t state)
580{ 597{
581 int i; 598 int i;
582 599
583 for (i = 0; i < num_var_ranges; i++) { 600 for (i = 0; i < num_var_ranges; i++) {
584 mtrr_if->get(i, 601 mtrr_if->get(i, &mtrr_value[i].lbase,
585 &mtrr_value[i].lbase, 602 &mtrr_value[i].lsize,
586 &mtrr_value[i].lsize, 603 &mtrr_value[i].ltype);
587 &mtrr_value[i].ltype);
588 } 604 }
589 return 0; 605 return 0;
590} 606}
591 607
592static int mtrr_restore(struct sys_device * sysdev) 608static int mtrr_restore(struct sys_device *sysdev)
593{ 609{
594 int i; 610 int i;
595 611
596 for (i = 0; i < num_var_ranges; i++) { 612 for (i = 0; i < num_var_ranges; i++) {
597 if (mtrr_value[i].lsize) 613 if (mtrr_value[i].lsize) {
598 set_mtrr(i, 614 set_mtrr(i, mtrr_value[i].lbase,
599 mtrr_value[i].lbase, 615 mtrr_value[i].lsize,
600 mtrr_value[i].lsize, 616 mtrr_value[i].ltype);
601 mtrr_value[i].ltype); 617 }
602 } 618 }
603 return 0; 619 return 0;
604} 620}
@@ -615,26 +631,29 @@ int __initdata changed_by_mtrr_cleanup;
615/** 631/**
616 * mtrr_bp_init - initialize mtrrs on the boot CPU 632 * mtrr_bp_init - initialize mtrrs on the boot CPU
617 * 633 *
618 * This needs to be called early; before any of the other CPUs are 634 * This needs to be called early; before any of the other CPUs are
619 * initialized (i.e. before smp_init()). 635 * initialized (i.e. before smp_init()).
620 * 636 *
621 */ 637 */
622void __init mtrr_bp_init(void) 638void __init mtrr_bp_init(void)
623{ 639{
624 u32 phys_addr; 640 u32 phys_addr;
641
625 init_ifs(); 642 init_ifs();
626 643
627 phys_addr = 32; 644 phys_addr = 32;
628 645
629 if (cpu_has_mtrr) { 646 if (cpu_has_mtrr) {
630 mtrr_if = &generic_mtrr_ops; 647 mtrr_if = &generic_mtrr_ops;
631 size_or_mask = 0xff000000; /* 36 bits */ 648 size_or_mask = 0xff000000; /* 36 bits */
632 size_and_mask = 0x00f00000; 649 size_and_mask = 0x00f00000;
633 phys_addr = 36; 650 phys_addr = 36;
634 651
635 /* This is an AMD specific MSR, but we assume(hope?) that 652 /*
636 Intel will implement it to when they extend the address 653 * This is an AMD specific MSR, but we assume(hope?) that
637 bus of the Xeon. */ 654 * Intel will implement it to when they extend the address
655 * bus of the Xeon.
656 */
638 if (cpuid_eax(0x80000000) >= 0x80000008) { 657 if (cpuid_eax(0x80000000) >= 0x80000008) {
639 phys_addr = cpuid_eax(0x80000008) & 0xff; 658 phys_addr = cpuid_eax(0x80000008) & 0xff;
640 /* CPUID workaround for Intel 0F33/0F34 CPU */ 659 /* CPUID workaround for Intel 0F33/0F34 CPU */
@@ -649,9 +668,11 @@ void __init mtrr_bp_init(void)
649 size_and_mask = ~size_or_mask & 0xfffff00000ULL; 668 size_and_mask = ~size_or_mask & 0xfffff00000ULL;
650 } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && 669 } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
651 boot_cpu_data.x86 == 6) { 670 boot_cpu_data.x86 == 6) {
652 /* VIA C* family have Intel style MTRRs, but 671 /*
653 don't support PAE */ 672 * VIA C* family have Intel style MTRRs,
654 size_or_mask = 0xfff00000; /* 32 bits */ 673 * but don't support PAE
674 */
675 size_or_mask = 0xfff00000; /* 32 bits */
655 size_and_mask = 0; 676 size_and_mask = 0;
656 phys_addr = 32; 677 phys_addr = 32;
657 } 678 }
@@ -694,7 +715,6 @@ void __init mtrr_bp_init(void)
694 changed_by_mtrr_cleanup = 1; 715 changed_by_mtrr_cleanup = 1;
695 mtrr_if->set_all(); 716 mtrr_if->set_all();
696 } 717 }
697
698 } 718 }
699 } 719 }
700} 720}
@@ -706,12 +726,17 @@ void mtrr_ap_init(void)
706 if (!mtrr_if || !use_intel()) 726 if (!mtrr_if || !use_intel())
707 return; 727 return;
708 /* 728 /*
709 * Ideally we should hold mtrr_mutex here to avoid mtrr entries changed, 729 * Ideally we should hold mtrr_mutex here to avoid mtrr entries
710 * but this routine will be called in cpu boot time, holding the lock 730 * changed, but this routine will be called in cpu boot time,
711 * breaks it. This routine is called in two cases: 1.very earily time 731 * holding the lock breaks it.
712 * of software resume, when there absolutely isn't mtrr entry changes; 732 *
713 * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to 733 * This routine is called in two cases:
714 * prevent mtrr entry changes 734 *
735 * 1. very earily time of software resume, when there absolutely
736 * isn't mtrr entry changes;
737 *
738 * 2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug
739 * lock to prevent mtrr entry changes
715 */ 740 */
716 local_irq_save(flags); 741 local_irq_save(flags);
717 742
@@ -732,19 +757,23 @@ static int __init mtrr_init_finialize(void)
732{ 757{
733 if (!mtrr_if) 758 if (!mtrr_if)
734 return 0; 759 return 0;
760
735 if (use_intel()) { 761 if (use_intel()) {
736 if (!changed_by_mtrr_cleanup) 762 if (!changed_by_mtrr_cleanup)
737 mtrr_state_warn(); 763 mtrr_state_warn();
738 } else { 764 return 0;
739 /* The CPUs haven't MTRR and seem to not support SMP. They have
740 * specific drivers, we use a tricky method to support
741 * suspend/resume for them.
742 * TBD: is there any system with such CPU which supports
743 * suspend/resume? if no, we should remove the code.
744 */
745 sysdev_driver_register(&cpu_sysdev_class,
746 &mtrr_sysdev_driver);
747 } 765 }
766
767 /*
768 * The CPU has no MTRR and seems to not support SMP. They have
769 * specific drivers, we use a tricky method to support
770 * suspend/resume for them.
771 *
772 * TBD: is there any system with such CPU which supports
773 * suspend/resume? If no, we should remove the code.
774 */
775 sysdev_driver_register(&cpu_sysdev_class, &mtrr_sysdev_driver);
776
748 return 0; 777 return 0;
749} 778}
750subsys_initcall(mtrr_init_finialize); 779subsys_initcall(mtrr_init_finialize);
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
index 7538b767f206..a501dee9a87a 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * local mtrr defines. 2 * local MTRR defines.
3 */ 3 */
4 4
5#include <linux/types.h> 5#include <linux/types.h>
@@ -14,13 +14,12 @@ extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
14struct mtrr_ops { 14struct mtrr_ops {
15 u32 vendor; 15 u32 vendor;
16 u32 use_intel_if; 16 u32 use_intel_if;
17// void (*init)(void);
18 void (*set)(unsigned int reg, unsigned long base, 17 void (*set)(unsigned int reg, unsigned long base,
19 unsigned long size, mtrr_type type); 18 unsigned long size, mtrr_type type);
20 void (*set_all)(void); 19 void (*set_all)(void);
21 20
22 void (*get)(unsigned int reg, unsigned long *base, 21 void (*get)(unsigned int reg, unsigned long *base,
23 unsigned long *size, mtrr_type * type); 22 unsigned long *size, mtrr_type *type);
24 int (*get_free_region)(unsigned long base, unsigned long size, 23 int (*get_free_region)(unsigned long base, unsigned long size,
25 int replace_reg); 24 int replace_reg);
26 int (*validate_add_page)(unsigned long base, unsigned long size, 25 int (*validate_add_page)(unsigned long base, unsigned long size,
@@ -39,11 +38,11 @@ extern int positive_have_wrcomb(void);
39 38
40/* library functions for processor-specific routines */ 39/* library functions for processor-specific routines */
41struct set_mtrr_context { 40struct set_mtrr_context {
42 unsigned long flags; 41 unsigned long flags;
43 unsigned long cr4val; 42 unsigned long cr4val;
44 u32 deftype_lo; 43 u32 deftype_lo;
45 u32 deftype_hi; 44 u32 deftype_hi;
46 u32 ccr3; 45 u32 ccr3;
47}; 46};
48 47
49void set_mtrr_done(struct set_mtrr_context *ctxt); 48void set_mtrr_done(struct set_mtrr_context *ctxt);
@@ -54,10 +53,10 @@ void fill_mtrr_var_range(unsigned int index,
54 u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi); 53 u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
55void get_mtrr_state(void); 54void get_mtrr_state(void);
56 55
57extern void set_mtrr_ops(struct mtrr_ops * ops); 56extern void set_mtrr_ops(struct mtrr_ops *ops);
58 57
59extern u64 size_or_mask, size_and_mask; 58extern u64 size_or_mask, size_and_mask;
60extern struct mtrr_ops * mtrr_if; 59extern struct mtrr_ops *mtrr_if;
61 60
62#define is_cpu(vnd) (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd) 61#define is_cpu(vnd) (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd)
63#define use_intel() (mtrr_if && mtrr_if->use_intel_if == 1) 62#define use_intel() (mtrr_if && mtrr_if->use_intel_if == 1)
diff --git a/arch/x86/kernel/cpu/mtrr/state.c b/arch/x86/kernel/cpu/mtrr/state.c
index 1f5fb1588d1f..dfc80b4e6b0d 100644
--- a/arch/x86/kernel/cpu/mtrr/state.c
+++ b/arch/x86/kernel/cpu/mtrr/state.c
@@ -1,24 +1,25 @@
1#include <linux/mm.h>
2#include <linux/init.h> 1#include <linux/init.h>
3#include <asm/io.h> 2#include <linux/io.h>
4#include <asm/mtrr.h> 3#include <linux/mm.h>
5#include <asm/msr.h> 4
6#include <asm/processor-cyrix.h> 5#include <asm/processor-cyrix.h>
7#include <asm/processor-flags.h> 6#include <asm/processor-flags.h>
8#include "mtrr.h" 7#include <asm/mtrr.h>
8#include <asm/msr.h>
9 9
10#include "mtrr.h"
10 11
11/* Put the processor into a state where MTRRs can be safely set */ 12/* Put the processor into a state where MTRRs can be safely set */
12void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) 13void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
13{ 14{
14 unsigned int cr0; 15 unsigned int cr0;
15 16
16 /* Disable interrupts locally */ 17 /* Disable interrupts locally */
17 local_irq_save(ctxt->flags); 18 local_irq_save(ctxt->flags);
18 19
19 if (use_intel() || is_cpu(CYRIX)) { 20 if (use_intel() || is_cpu(CYRIX)) {
20 21
21 /* Save value of CR4 and clear Page Global Enable (bit 7) */ 22 /* Save value of CR4 and clear Page Global Enable (bit 7) */
22 if (cpu_has_pge) { 23 if (cpu_has_pge) {
23 ctxt->cr4val = read_cr4(); 24 ctxt->cr4val = read_cr4();
24 write_cr4(ctxt->cr4val & ~X86_CR4_PGE); 25 write_cr4(ctxt->cr4val & ~X86_CR4_PGE);
@@ -33,50 +34,61 @@ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
33 write_cr0(cr0); 34 write_cr0(cr0);
34 wbinvd(); 35 wbinvd();
35 36
36 if (use_intel()) 37 if (use_intel()) {
37 /* Save MTRR state */ 38 /* Save MTRR state */
38 rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi); 39 rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
39 else 40 } else {
40 /* Cyrix ARRs - everything else were excluded at the top */ 41 /*
42 * Cyrix ARRs -
43 * everything else were excluded at the top
44 */
41 ctxt->ccr3 = getCx86(CX86_CCR3); 45 ctxt->ccr3 = getCx86(CX86_CCR3);
46 }
42 } 47 }
43} 48}
44 49
45void set_mtrr_cache_disable(struct set_mtrr_context *ctxt) 50void set_mtrr_cache_disable(struct set_mtrr_context *ctxt)
46{ 51{
47 if (use_intel()) 52 if (use_intel()) {
48 /* Disable MTRRs, and set the default type to uncached */ 53 /* Disable MTRRs, and set the default type to uncached */
49 mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, 54 mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL,
50 ctxt->deftype_hi); 55 ctxt->deftype_hi);
51 else if (is_cpu(CYRIX)) 56 } else {
52 /* Cyrix ARRs - everything else were excluded at the top */ 57 if (is_cpu(CYRIX)) {
53 setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10); 58 /* Cyrix ARRs - everything else were excluded at the top */
59 setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10);
60 }
61 }
54} 62}
55 63
56/* Restore the processor after a set_mtrr_prepare */ 64/* Restore the processor after a set_mtrr_prepare */
57void set_mtrr_done(struct set_mtrr_context *ctxt) 65void set_mtrr_done(struct set_mtrr_context *ctxt)
58{ 66{
59 if (use_intel() || is_cpu(CYRIX)) { 67 if (use_intel() || is_cpu(CYRIX)) {
60 68
61 /* Flush caches and TLBs */ 69 /* Flush caches and TLBs */
62 wbinvd(); 70 wbinvd();
63 71
64 /* Restore MTRRdefType */ 72 /* Restore MTRRdefType */
65 if (use_intel()) 73 if (use_intel()) {
66 /* Intel (P6) standard MTRRs */ 74 /* Intel (P6) standard MTRRs */
67 mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi); 75 mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo,
68 else 76 ctxt->deftype_hi);
69 /* Cyrix ARRs - everything else was excluded at the top */ 77 } else {
78 /*
79 * Cyrix ARRs -
80 * everything else was excluded at the top
81 */
70 setCx86(CX86_CCR3, ctxt->ccr3); 82 setCx86(CX86_CCR3, ctxt->ccr3);
83 }
71 84
72 /* Enable caches */ 85 /* Enable caches */
73 write_cr0(read_cr0() & 0xbfffffff); 86 write_cr0(read_cr0() & 0xbfffffff);
74 87
75 /* Restore value of CR4 */ 88 /* Restore value of CR4 */
76 if (cpu_has_pge) 89 if (cpu_has_pge)
77 write_cr4(ctxt->cr4val); 90 write_cr4(ctxt->cr4val);
78 } 91 }
79 /* Re-enable interrupts locally (if enabled previously) */ 92 /* Re-enable interrupts locally (if enabled previously) */
80 local_irq_restore(ctxt->flags); 93 local_irq_restore(ctxt->flags);
81} 94}
82
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index 900332b800f8..f9cd0849bd42 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -6,6 +6,7 @@
6 * Copyright (C) 2009 Jaswinder Singh Rajput 6 * Copyright (C) 2009 Jaswinder Singh Rajput
7 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter 7 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
8 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> 8 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
9 * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
9 * 10 *
10 * For licencing details see kernel-base/COPYING 11 * For licencing details see kernel-base/COPYING
11 */ 12 */
@@ -20,6 +21,7 @@
20#include <linux/sched.h> 21#include <linux/sched.h>
21#include <linux/uaccess.h> 22#include <linux/uaccess.h>
22#include <linux/highmem.h> 23#include <linux/highmem.h>
24#include <linux/cpu.h>
23 25
24#include <asm/apic.h> 26#include <asm/apic.h>
25#include <asm/stacktrace.h> 27#include <asm/stacktrace.h>
@@ -27,12 +29,52 @@
27 29
28static u64 perf_counter_mask __read_mostly; 30static u64 perf_counter_mask __read_mostly;
29 31
32/* The maximal number of PEBS counters: */
33#define MAX_PEBS_COUNTERS 4
34
35/* The size of a BTS record in bytes: */
36#define BTS_RECORD_SIZE 24
37
38/* The size of a per-cpu BTS buffer in bytes: */
39#define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 1024)
40
41/* The BTS overflow threshold in bytes from the end of the buffer: */
42#define BTS_OVFL_TH (BTS_RECORD_SIZE * 64)
43
44
45/*
46 * Bits in the debugctlmsr controlling branch tracing.
47 */
48#define X86_DEBUGCTL_TR (1 << 6)
49#define X86_DEBUGCTL_BTS (1 << 7)
50#define X86_DEBUGCTL_BTINT (1 << 8)
51#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9)
52#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10)
53
54/*
55 * A debug store configuration.
56 *
57 * We only support architectures that use 64bit fields.
58 */
59struct debug_store {
60 u64 bts_buffer_base;
61 u64 bts_index;
62 u64 bts_absolute_maximum;
63 u64 bts_interrupt_threshold;
64 u64 pebs_buffer_base;
65 u64 pebs_index;
66 u64 pebs_absolute_maximum;
67 u64 pebs_interrupt_threshold;
68 u64 pebs_counter_reset[MAX_PEBS_COUNTERS];
69};
70
30struct cpu_hw_counters { 71struct cpu_hw_counters {
31 struct perf_counter *counters[X86_PMC_IDX_MAX]; 72 struct perf_counter *counters[X86_PMC_IDX_MAX];
32 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; 73 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
33 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; 74 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
34 unsigned long interrupts; 75 unsigned long interrupts;
35 int enabled; 76 int enabled;
77 struct debug_store *ds;
36}; 78};
37 79
38/* 80/*
@@ -58,6 +100,8 @@ struct x86_pmu {
58 int apic; 100 int apic;
59 u64 max_period; 101 u64 max_period;
60 u64 intel_ctrl; 102 u64 intel_ctrl;
103 void (*enable_bts)(u64 config);
104 void (*disable_bts)(void);
61}; 105};
62 106
63static struct x86_pmu x86_pmu __read_mostly; 107static struct x86_pmu x86_pmu __read_mostly;
@@ -577,6 +621,9 @@ x86_perf_counter_update(struct perf_counter *counter,
577 u64 prev_raw_count, new_raw_count; 621 u64 prev_raw_count, new_raw_count;
578 s64 delta; 622 s64 delta;
579 623
624 if (idx == X86_PMC_IDX_FIXED_BTS)
625 return 0;
626
580 /* 627 /*
581 * Careful: an NMI might modify the previous counter value. 628 * Careful: an NMI might modify the previous counter value.
582 * 629 *
@@ -666,10 +713,110 @@ static void release_pmc_hardware(void)
666#endif 713#endif
667} 714}
668 715
716static inline bool bts_available(void)
717{
718 return x86_pmu.enable_bts != NULL;
719}
720
721static inline void init_debug_store_on_cpu(int cpu)
722{
723 struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds;
724
725 if (!ds)
726 return;
727
728 wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
729 (u32)((u64)(unsigned long)ds),
730 (u32)((u64)(unsigned long)ds >> 32));
731}
732
733static inline void fini_debug_store_on_cpu(int cpu)
734{
735 if (!per_cpu(cpu_hw_counters, cpu).ds)
736 return;
737
738 wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
739}
740
741static void release_bts_hardware(void)
742{
743 int cpu;
744
745 if (!bts_available())
746 return;
747
748 get_online_cpus();
749
750 for_each_online_cpu(cpu)
751 fini_debug_store_on_cpu(cpu);
752
753 for_each_possible_cpu(cpu) {
754 struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds;
755
756 if (!ds)
757 continue;
758
759 per_cpu(cpu_hw_counters, cpu).ds = NULL;
760
761 kfree((void *)(unsigned long)ds->bts_buffer_base);
762 kfree(ds);
763 }
764
765 put_online_cpus();
766}
767
768static int reserve_bts_hardware(void)
769{
770 int cpu, err = 0;
771
772 if (!bts_available())
773 return 0;
774
775 get_online_cpus();
776
777 for_each_possible_cpu(cpu) {
778 struct debug_store *ds;
779 void *buffer;
780
781 err = -ENOMEM;
782 buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
783 if (unlikely(!buffer))
784 break;
785
786 ds = kzalloc(sizeof(*ds), GFP_KERNEL);
787 if (unlikely(!ds)) {
788 kfree(buffer);
789 break;
790 }
791
792 ds->bts_buffer_base = (u64)(unsigned long)buffer;
793 ds->bts_index = ds->bts_buffer_base;
794 ds->bts_absolute_maximum =
795 ds->bts_buffer_base + BTS_BUFFER_SIZE;
796 ds->bts_interrupt_threshold =
797 ds->bts_absolute_maximum - BTS_OVFL_TH;
798
799 per_cpu(cpu_hw_counters, cpu).ds = ds;
800 err = 0;
801 }
802
803 if (err)
804 release_bts_hardware();
805 else {
806 for_each_online_cpu(cpu)
807 init_debug_store_on_cpu(cpu);
808 }
809
810 put_online_cpus();
811
812 return err;
813}
814
669static void hw_perf_counter_destroy(struct perf_counter *counter) 815static void hw_perf_counter_destroy(struct perf_counter *counter)
670{ 816{
671 if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) { 817 if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) {
672 release_pmc_hardware(); 818 release_pmc_hardware();
819 release_bts_hardware();
673 mutex_unlock(&pmc_reserve_mutex); 820 mutex_unlock(&pmc_reserve_mutex);
674 } 821 }
675} 822}
@@ -712,6 +859,42 @@ set_ext_hw_attr(struct hw_perf_counter *hwc, struct perf_counter_attr *attr)
712 return 0; 859 return 0;
713} 860}
714 861
862static void intel_pmu_enable_bts(u64 config)
863{
864 unsigned long debugctlmsr;
865
866 debugctlmsr = get_debugctlmsr();
867
868 debugctlmsr |= X86_DEBUGCTL_TR;
869 debugctlmsr |= X86_DEBUGCTL_BTS;
870 debugctlmsr |= X86_DEBUGCTL_BTINT;
871
872 if (!(config & ARCH_PERFMON_EVENTSEL_OS))
873 debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
874
875 if (!(config & ARCH_PERFMON_EVENTSEL_USR))
876 debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
877
878 update_debugctlmsr(debugctlmsr);
879}
880
881static void intel_pmu_disable_bts(void)
882{
883 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
884 unsigned long debugctlmsr;
885
886 if (!cpuc->ds)
887 return;
888
889 debugctlmsr = get_debugctlmsr();
890
891 debugctlmsr &=
892 ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
893 X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
894
895 update_debugctlmsr(debugctlmsr);
896}
897
715/* 898/*
716 * Setup the hardware configuration for a given attr_type 899 * Setup the hardware configuration for a given attr_type
717 */ 900 */
@@ -728,9 +911,13 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
728 err = 0; 911 err = 0;
729 if (!atomic_inc_not_zero(&active_counters)) { 912 if (!atomic_inc_not_zero(&active_counters)) {
730 mutex_lock(&pmc_reserve_mutex); 913 mutex_lock(&pmc_reserve_mutex);
731 if (atomic_read(&active_counters) == 0 && !reserve_pmc_hardware()) 914 if (atomic_read(&active_counters) == 0) {
732 err = -EBUSY; 915 if (!reserve_pmc_hardware())
733 else 916 err = -EBUSY;
917 else
918 err = reserve_bts_hardware();
919 }
920 if (!err)
734 atomic_inc(&active_counters); 921 atomic_inc(&active_counters);
735 mutex_unlock(&pmc_reserve_mutex); 922 mutex_unlock(&pmc_reserve_mutex);
736 } 923 }
@@ -793,6 +980,20 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
793 if (config == -1LL) 980 if (config == -1LL)
794 return -EINVAL; 981 return -EINVAL;
795 982
983 /*
984 * Branch tracing:
985 */
986 if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
987 (hwc->sample_period == 1)) {
988 /* BTS is not supported by this architecture. */
989 if (!bts_available())
990 return -EOPNOTSUPP;
991
992 /* BTS is currently only allowed for user-mode. */
993 if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
994 return -EOPNOTSUPP;
995 }
996
796 hwc->config |= config; 997 hwc->config |= config;
797 998
798 return 0; 999 return 0;
@@ -817,7 +1018,18 @@ static void p6_pmu_disable_all(void)
817 1018
818static void intel_pmu_disable_all(void) 1019static void intel_pmu_disable_all(void)
819{ 1020{
1021 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
1022
1023 if (!cpuc->enabled)
1024 return;
1025
1026 cpuc->enabled = 0;
1027 barrier();
1028
820 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); 1029 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
1030
1031 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
1032 intel_pmu_disable_bts();
821} 1033}
822 1034
823static void amd_pmu_disable_all(void) 1035static void amd_pmu_disable_all(void)
@@ -875,7 +1087,25 @@ static void p6_pmu_enable_all(void)
875 1087
876static void intel_pmu_enable_all(void) 1088static void intel_pmu_enable_all(void)
877{ 1089{
1090 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
1091
1092 if (cpuc->enabled)
1093 return;
1094
1095 cpuc->enabled = 1;
1096 barrier();
1097
878 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); 1098 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
1099
1100 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
1101 struct perf_counter *counter =
1102 cpuc->counters[X86_PMC_IDX_FIXED_BTS];
1103
1104 if (WARN_ON_ONCE(!counter))
1105 return;
1106
1107 intel_pmu_enable_bts(counter->hw.config);
1108 }
879} 1109}
880 1110
881static void amd_pmu_enable_all(void) 1111static void amd_pmu_enable_all(void)
@@ -962,6 +1192,11 @@ p6_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
962static inline void 1192static inline void
963intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) 1193intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
964{ 1194{
1195 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1196 intel_pmu_disable_bts();
1197 return;
1198 }
1199
965 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 1200 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
966 intel_pmu_disable_fixed(hwc, idx); 1201 intel_pmu_disable_fixed(hwc, idx);
967 return; 1202 return;
@@ -990,6 +1225,9 @@ x86_perf_counter_set_period(struct perf_counter *counter,
990 s64 period = hwc->sample_period; 1225 s64 period = hwc->sample_period;
991 int err, ret = 0; 1226 int err, ret = 0;
992 1227
1228 if (idx == X86_PMC_IDX_FIXED_BTS)
1229 return 0;
1230
993 /* 1231 /*
994 * If we are way outside a reasoable range then just skip forward: 1232 * If we are way outside a reasoable range then just skip forward:
995 */ 1233 */
@@ -1072,6 +1310,14 @@ static void p6_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
1072 1310
1073static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) 1311static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
1074{ 1312{
1313 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1314 if (!__get_cpu_var(cpu_hw_counters).enabled)
1315 return;
1316
1317 intel_pmu_enable_bts(hwc->config);
1318 return;
1319 }
1320
1075 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 1321 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
1076 intel_pmu_enable_fixed(hwc, idx); 1322 intel_pmu_enable_fixed(hwc, idx);
1077 return; 1323 return;
@@ -1093,11 +1339,16 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc)
1093{ 1339{
1094 unsigned int event; 1340 unsigned int event;
1095 1341
1342 event = hwc->config & ARCH_PERFMON_EVENT_MASK;
1343
1344 if (unlikely((event ==
1345 x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
1346 (hwc->sample_period == 1)))
1347 return X86_PMC_IDX_FIXED_BTS;
1348
1096 if (!x86_pmu.num_counters_fixed) 1349 if (!x86_pmu.num_counters_fixed)
1097 return -1; 1350 return -1;
1098 1351
1099 event = hwc->config & ARCH_PERFMON_EVENT_MASK;
1100
1101 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) 1352 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
1102 return X86_PMC_IDX_FIXED_INSTRUCTIONS; 1353 return X86_PMC_IDX_FIXED_INSTRUCTIONS;
1103 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES))) 1354 if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
@@ -1118,7 +1369,15 @@ static int x86_pmu_enable(struct perf_counter *counter)
1118 int idx; 1369 int idx;
1119 1370
1120 idx = fixed_mode_idx(counter, hwc); 1371 idx = fixed_mode_idx(counter, hwc);
1121 if (idx >= 0) { 1372 if (idx == X86_PMC_IDX_FIXED_BTS) {
1373 /* BTS is already occupied. */
1374 if (test_and_set_bit(idx, cpuc->used_mask))
1375 return -EAGAIN;
1376
1377 hwc->config_base = 0;
1378 hwc->counter_base = 0;
1379 hwc->idx = idx;
1380 } else if (idx >= 0) {
1122 /* 1381 /*
1123 * Try to get the fixed counter, if that is already taken 1382 * Try to get the fixed counter, if that is already taken
1124 * then try to get a generic counter: 1383 * then try to get a generic counter:
@@ -1229,6 +1488,44 @@ void perf_counter_print_debug(void)
1229 local_irq_restore(flags); 1488 local_irq_restore(flags);
1230} 1489}
1231 1490
1491static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
1492 struct perf_sample_data *data)
1493{
1494 struct debug_store *ds = cpuc->ds;
1495 struct bts_record {
1496 u64 from;
1497 u64 to;
1498 u64 flags;
1499 };
1500 struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS];
1501 unsigned long orig_ip = data->regs->ip;
1502 struct bts_record *at, *top;
1503
1504 if (!counter)
1505 return;
1506
1507 if (!ds)
1508 return;
1509
1510 at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
1511 top = (struct bts_record *)(unsigned long)ds->bts_index;
1512
1513 ds->bts_index = ds->bts_buffer_base;
1514
1515 for (; at < top; at++) {
1516 data->regs->ip = at->from;
1517 data->addr = at->to;
1518
1519 perf_counter_output(counter, 1, data);
1520 }
1521
1522 data->regs->ip = orig_ip;
1523 data->addr = 0;
1524
1525 /* There's new data available. */
1526 counter->pending_kill = POLL_IN;
1527}
1528
1232static void x86_pmu_disable(struct perf_counter *counter) 1529static void x86_pmu_disable(struct perf_counter *counter)
1233{ 1530{
1234 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); 1531 struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
@@ -1253,6 +1550,15 @@ static void x86_pmu_disable(struct perf_counter *counter)
1253 * that we are disabling: 1550 * that we are disabling:
1254 */ 1551 */
1255 x86_perf_counter_update(counter, hwc, idx); 1552 x86_perf_counter_update(counter, hwc, idx);
1553
1554 /* Drain the remaining BTS records. */
1555 if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
1556 struct perf_sample_data data;
1557 struct pt_regs regs;
1558
1559 data.regs = &regs;
1560 intel_pmu_drain_bts_buffer(cpuc, &data);
1561 }
1256 cpuc->counters[idx] = NULL; 1562 cpuc->counters[idx] = NULL;
1257 clear_bit(idx, cpuc->used_mask); 1563 clear_bit(idx, cpuc->used_mask);
1258 1564
@@ -1280,6 +1586,7 @@ static int intel_pmu_save_and_restart(struct perf_counter *counter)
1280 1586
1281static void intel_pmu_reset(void) 1587static void intel_pmu_reset(void)
1282{ 1588{
1589 struct debug_store *ds = __get_cpu_var(cpu_hw_counters).ds;
1283 unsigned long flags; 1590 unsigned long flags;
1284 int idx; 1591 int idx;
1285 1592
@@ -1297,6 +1604,8 @@ static void intel_pmu_reset(void)
1297 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) { 1604 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
1298 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); 1605 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
1299 } 1606 }
1607 if (ds)
1608 ds->bts_index = ds->bts_buffer_base;
1300 1609
1301 local_irq_restore(flags); 1610 local_irq_restore(flags);
1302} 1611}
@@ -1362,6 +1671,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
1362 cpuc = &__get_cpu_var(cpu_hw_counters); 1671 cpuc = &__get_cpu_var(cpu_hw_counters);
1363 1672
1364 perf_disable(); 1673 perf_disable();
1674 intel_pmu_drain_bts_buffer(cpuc, &data);
1365 status = intel_pmu_get_status(); 1675 status = intel_pmu_get_status();
1366 if (!status) { 1676 if (!status) {
1367 perf_enable(); 1677 perf_enable();
@@ -1571,6 +1881,8 @@ static struct x86_pmu intel_pmu = {
1571 * the generic counter period: 1881 * the generic counter period:
1572 */ 1882 */
1573 .max_period = (1ULL << 31) - 1, 1883 .max_period = (1ULL << 31) - 1,
1884 .enable_bts = intel_pmu_enable_bts,
1885 .disable_bts = intel_pmu_disable_bts,
1574}; 1886};
1575 1887
1576static struct x86_pmu amd_pmu = { 1888static struct x86_pmu amd_pmu = {
@@ -1962,3 +2274,8 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
1962 2274
1963 return entry; 2275 return entry;
1964} 2276}
2277
2278void hw_perf_counter_setup_online(int cpu)
2279{
2280 init_debug_store_on_cpu(cpu);
2281}
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index e60ed740d2b3..392bea43b890 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -68,16 +68,16 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
68 /* returns the bit offset of the performance counter register */ 68 /* returns the bit offset of the performance counter register */
69 switch (boot_cpu_data.x86_vendor) { 69 switch (boot_cpu_data.x86_vendor) {
70 case X86_VENDOR_AMD: 70 case X86_VENDOR_AMD:
71 return (msr - MSR_K7_PERFCTR0); 71 return msr - MSR_K7_PERFCTR0;
72 case X86_VENDOR_INTEL: 72 case X86_VENDOR_INTEL:
73 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) 73 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
74 return (msr - MSR_ARCH_PERFMON_PERFCTR0); 74 return msr - MSR_ARCH_PERFMON_PERFCTR0;
75 75
76 switch (boot_cpu_data.x86) { 76 switch (boot_cpu_data.x86) {
77 case 6: 77 case 6:
78 return (msr - MSR_P6_PERFCTR0); 78 return msr - MSR_P6_PERFCTR0;
79 case 15: 79 case 15:
80 return (msr - MSR_P4_BPU_PERFCTR0); 80 return msr - MSR_P4_BPU_PERFCTR0;
81 } 81 }
82 } 82 }
83 return 0; 83 return 0;
@@ -92,16 +92,16 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
92 /* returns the bit offset of the event selection register */ 92 /* returns the bit offset of the event selection register */
93 switch (boot_cpu_data.x86_vendor) { 93 switch (boot_cpu_data.x86_vendor) {
94 case X86_VENDOR_AMD: 94 case X86_VENDOR_AMD:
95 return (msr - MSR_K7_EVNTSEL0); 95 return msr - MSR_K7_EVNTSEL0;
96 case X86_VENDOR_INTEL: 96 case X86_VENDOR_INTEL:
97 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) 97 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
98 return (msr - MSR_ARCH_PERFMON_EVENTSEL0); 98 return msr - MSR_ARCH_PERFMON_EVENTSEL0;
99 99
100 switch (boot_cpu_data.x86) { 100 switch (boot_cpu_data.x86) {
101 case 6: 101 case 6:
102 return (msr - MSR_P6_EVNTSEL0); 102 return msr - MSR_P6_EVNTSEL0;
103 case 15: 103 case 15:
104 return (msr - MSR_P4_BSU_ESCR0); 104 return msr - MSR_P4_BSU_ESCR0;
105 } 105 }
106 } 106 }
107 return 0; 107 return 0;
@@ -113,7 +113,7 @@ int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
113{ 113{
114 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 114 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
115 115
116 return (!test_bit(counter, perfctr_nmi_owner)); 116 return !test_bit(counter, perfctr_nmi_owner);
117} 117}
118 118
119/* checks the an msr for availability */ 119/* checks the an msr for availability */
@@ -124,7 +124,7 @@ int avail_to_resrv_perfctr_nmi(unsigned int msr)
124 counter = nmi_perfctr_msr_to_bit(msr); 124 counter = nmi_perfctr_msr_to_bit(msr);
125 BUG_ON(counter > NMI_MAX_COUNTER_BITS); 125 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
126 126
127 return (!test_bit(counter, perfctr_nmi_owner)); 127 return !test_bit(counter, perfctr_nmi_owner);
128} 128}
129EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); 129EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
130 130
@@ -237,7 +237,7 @@ static unsigned int adjust_for_32bit_ctr(unsigned int hz)
237 */ 237 */
238 counter_val = (u64)cpu_khz * 1000; 238 counter_val = (u64)cpu_khz * 1000;
239 do_div(counter_val, retval); 239 do_div(counter_val, retval);
240 if (counter_val > 0x7fffffffULL) { 240 if (counter_val > 0x7fffffffULL) {
241 u64 count = (u64)cpu_khz * 1000; 241 u64 count = (u64)cpu_khz * 1000;
242 do_div(count, 0x7fffffffUL); 242 do_div(count, 0x7fffffffUL);
243 retval = count + 1; 243 retval = count + 1;
@@ -251,7 +251,7 @@ static void write_watchdog_counter(unsigned int perfctr_msr,
251 u64 count = (u64)cpu_khz * 1000; 251 u64 count = (u64)cpu_khz * 1000;
252 252
253 do_div(count, nmi_hz); 253 do_div(count, nmi_hz);
254 if(descr) 254 if (descr)
255 pr_debug("setting %s to -0x%08Lx\n", descr, count); 255 pr_debug("setting %s to -0x%08Lx\n", descr, count);
256 wrmsrl(perfctr_msr, 0 - count); 256 wrmsrl(perfctr_msr, 0 - count);
257} 257}
@@ -262,7 +262,7 @@ static void write_watchdog_counter32(unsigned int perfctr_msr,
262 u64 count = (u64)cpu_khz * 1000; 262 u64 count = (u64)cpu_khz * 1000;
263 263
264 do_div(count, nmi_hz); 264 do_div(count, nmi_hz);
265 if(descr) 265 if (descr)
266 pr_debug("setting %s to -0x%08Lx\n", descr, count); 266 pr_debug("setting %s to -0x%08Lx\n", descr, count);
267 wrmsr(perfctr_msr, (u32)(-count), 0); 267 wrmsr(perfctr_msr, (u32)(-count), 0);
268} 268}
@@ -296,7 +296,7 @@ static int setup_k7_watchdog(unsigned nmi_hz)
296 296
297 /* setup the timer */ 297 /* setup the timer */
298 wrmsr(evntsel_msr, evntsel, 0); 298 wrmsr(evntsel_msr, evntsel, 0);
299 write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz); 299 write_watchdog_counter(perfctr_msr, "K7_PERFCTR0", nmi_hz);
300 300
301 /* initialize the wd struct before enabling */ 301 /* initialize the wd struct before enabling */
302 wd->perfctr_msr = perfctr_msr; 302 wd->perfctr_msr = perfctr_msr;
@@ -387,7 +387,7 @@ static int setup_p6_watchdog(unsigned nmi_hz)
387 /* setup the timer */ 387 /* setup the timer */
388 wrmsr(evntsel_msr, evntsel, 0); 388 wrmsr(evntsel_msr, evntsel, 0);
389 nmi_hz = adjust_for_32bit_ctr(nmi_hz); 389 nmi_hz = adjust_for_32bit_ctr(nmi_hz);
390 write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz); 390 write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0", nmi_hz);
391 391
392 /* initialize the wd struct before enabling */ 392 /* initialize the wd struct before enabling */
393 wd->perfctr_msr = perfctr_msr; 393 wd->perfctr_msr = perfctr_msr;
@@ -415,7 +415,7 @@ static void __kprobes p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
415 apic_write(APIC_LVTPC, APIC_DM_NMI); 415 apic_write(APIC_LVTPC, APIC_DM_NMI);
416 416
417 /* P6/ARCH_PERFMON has 32 bit counter write */ 417 /* P6/ARCH_PERFMON has 32 bit counter write */
418 write_watchdog_counter32(wd->perfctr_msr, NULL,nmi_hz); 418 write_watchdog_counter32(wd->perfctr_msr, NULL, nmi_hz);
419} 419}
420 420
421static const struct wd_ops p6_wd_ops = { 421static const struct wd_ops p6_wd_ops = {
@@ -490,9 +490,9 @@ static int setup_p4_watchdog(unsigned nmi_hz)
490 if (smp_num_siblings == 2) { 490 if (smp_num_siblings == 2) {
491 unsigned int ebx, apicid; 491 unsigned int ebx, apicid;
492 492
493 ebx = cpuid_ebx(1); 493 ebx = cpuid_ebx(1);
494 apicid = (ebx >> 24) & 0xff; 494 apicid = (ebx >> 24) & 0xff;
495 ht_num = apicid & 1; 495 ht_num = apicid & 1;
496 } else 496 } else
497#endif 497#endif
498 ht_num = 0; 498 ht_num = 0;
@@ -544,7 +544,7 @@ static int setup_p4_watchdog(unsigned nmi_hz)
544 } 544 }
545 545
546 evntsel = P4_ESCR_EVENT_SELECT(0x3F) 546 evntsel = P4_ESCR_EVENT_SELECT(0x3F)
547 | P4_ESCR_OS 547 | P4_ESCR_OS
548 | P4_ESCR_USR; 548 | P4_ESCR_USR;
549 549
550 cccr_val |= P4_CCCR_THRESHOLD(15) 550 cccr_val |= P4_CCCR_THRESHOLD(15)
@@ -612,7 +612,7 @@ static void __kprobes p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
612{ 612{
613 unsigned dummy; 613 unsigned dummy;
614 /* 614 /*
615 * P4 quirks: 615 * P4 quirks:
616 * - An overflown perfctr will assert its interrupt 616 * - An overflown perfctr will assert its interrupt
617 * until the OVF flag in its CCCR is cleared. 617 * until the OVF flag in its CCCR is cleared.
618 * - LVTPC is masked on interrupt and must be 618 * - LVTPC is masked on interrupt and must be
@@ -662,7 +662,8 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
662 * NOTE: Corresponding bit = 0 in ebx indicates event present. 662 * NOTE: Corresponding bit = 0 in ebx indicates event present.
663 */ 663 */
664 cpuid(10, &(eax.full), &ebx, &unused, &unused); 664 cpuid(10, &(eax.full), &ebx, &unused, &unused);
665 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || 665 if ((eax.split.mask_length <
666 (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
666 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) 667 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
667 return 0; 668 return 0;
668 669
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index d5e30397246b..62ac8cb6ba27 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -116,11 +116,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
116 seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize); 116 seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
117#endif 117#endif
118 seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size); 118 seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size);
119#ifdef CONFIG_X86_64
120 seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment); 119 seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
121 seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", 120 seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
122 c->x86_phys_bits, c->x86_virt_bits); 121 c->x86_phys_bits, c->x86_virt_bits);
123#endif
124 122
125 seq_printf(m, "power management:"); 123 seq_printf(m, "power management:");
126 for (i = 0; i < 32; i++) { 124 for (i = 0; i < 32; i++) {
@@ -128,7 +126,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
128 if (i < ARRAY_SIZE(x86_power_flags) && 126 if (i < ARRAY_SIZE(x86_power_flags) &&
129 x86_power_flags[i]) 127 x86_power_flags[i])
130 seq_printf(m, "%s%s", 128 seq_printf(m, "%s%s",
131 x86_power_flags[i][0]?" ":"", 129 x86_power_flags[i][0] ? " " : "",
132 x86_power_flags[i]); 130 x86_power_flags[i]);
133 else 131 else
134 seq_printf(m, " [%d]", i); 132 seq_printf(m, " [%d]", i);
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 284c399e3234..bc24f514ec93 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -49,17 +49,17 @@ static inline int __vmware_platform(void)
49 49
50static unsigned long __vmware_get_tsc_khz(void) 50static unsigned long __vmware_get_tsc_khz(void)
51{ 51{
52 uint64_t tsc_hz; 52 uint64_t tsc_hz;
53 uint32_t eax, ebx, ecx, edx; 53 uint32_t eax, ebx, ecx, edx;
54 54
55 VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); 55 VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
56 56
57 if (ebx == UINT_MAX) 57 if (ebx == UINT_MAX)
58 return 0; 58 return 0;
59 tsc_hz = eax | (((uint64_t)ebx) << 32); 59 tsc_hz = eax | (((uint64_t)ebx) << 32);
60 do_div(tsc_hz, 1000); 60 do_div(tsc_hz, 1000);
61 BUG_ON(tsc_hz >> 32); 61 BUG_ON(tsc_hz >> 32);
62 return tsc_hz; 62 return tsc_hz;
63} 63}
64 64
65/* 65/*
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index b4f14c6c09d9..37250fe490b1 100644
--- a/arch/x86/kernel/doublefault_32.c
+++ b/arch/x86/kernel/doublefault_32.c
@@ -27,9 +27,7 @@ static void doublefault_fn(void)
27 27
28 if (ptr_ok(gdt)) { 28 if (ptr_ok(gdt)) {
29 gdt += GDT_ENTRY_TSS << 3; 29 gdt += GDT_ENTRY_TSS << 3;
30 tss = *(u16 *)(gdt+2); 30 tss = get_desc_base((struct desc_struct *)gdt);
31 tss += *(u8 *)(gdt+4) << 16;
32 tss += *(u8 *)(gdt+7) << 24;
33 printk(KERN_EMERG "double fault, tss at %08lx\n", tss); 31 printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
34 32
35 if (ptr_ok(tss)) { 33 if (ptr_ok(tss)) {
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index 48bfe1386038..ef42a038f1a6 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -509,15 +509,15 @@ enum bts_field {
509 bts_escape = ((unsigned long)-1 & ~bts_qual_mask) 509 bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
510}; 510};
511 511
512static inline unsigned long bts_get(const char *base, enum bts_field field) 512static inline unsigned long bts_get(const char *base, unsigned long field)
513{ 513{
514 base += (ds_cfg.sizeof_ptr_field * field); 514 base += (ds_cfg.sizeof_ptr_field * field);
515 return *(unsigned long *)base; 515 return *(unsigned long *)base;
516} 516}
517 517
518static inline void bts_set(char *base, enum bts_field field, unsigned long val) 518static inline void bts_set(char *base, unsigned long field, unsigned long val)
519{ 519{
520 base += (ds_cfg.sizeof_ptr_field * field);; 520 base += (ds_cfg.sizeof_ptr_field * field);
521 (*(unsigned long *)base) = val; 521 (*(unsigned long *)base) = val;
522} 522}
523 523
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index c8405718a4c3..2d8a371d4339 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -15,7 +15,6 @@
15#include <linux/bug.h> 15#include <linux/bug.h>
16#include <linux/nmi.h> 16#include <linux/nmi.h>
17#include <linux/sysfs.h> 17#include <linux/sysfs.h>
18#include <linux/ftrace.h>
19 18
20#include <asm/stacktrace.h> 19#include <asm/stacktrace.h>
21 20
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 5cb5725b2bae..147005a1cc3c 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -115,7 +115,7 @@ static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
115{ 115{
116 int x = e820x->nr_map; 116 int x = e820x->nr_map;
117 117
118 if (x == ARRAY_SIZE(e820x->map)) { 118 if (x >= ARRAY_SIZE(e820x->map)) {
119 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); 119 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
120 return; 120 return;
121 } 121 }
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index cc827ac9e8d3..7ffec6b3b331 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -439,7 +439,6 @@ is386: movl $2,%ecx # set MP
439 jne 1f 439 jne 1f
440 movl $per_cpu__gdt_page,%eax 440 movl $per_cpu__gdt_page,%eax
441 movl $per_cpu__stack_canary,%ecx 441 movl $per_cpu__stack_canary,%ecx
442 subl $20, %ecx
443 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax) 442 movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
444 shrl $16, %ecx 443 shrl $16, %ecx
445 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax) 444 movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 3b09634a5153..7d35d0fe2329 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -218,7 +218,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
218void fixup_irqs(void) 218void fixup_irqs(void)
219{ 219{
220 unsigned int irq; 220 unsigned int irq;
221 static int warned;
222 struct irq_desc *desc; 221 struct irq_desc *desc;
223 222
224 for_each_irq_desc(irq, desc) { 223 for_each_irq_desc(irq, desc) {
@@ -236,8 +235,8 @@ void fixup_irqs(void)
236 } 235 }
237 if (desc->chip->set_affinity) 236 if (desc->chip->set_affinity)
238 desc->chip->set_affinity(irq, affinity); 237 desc->chip->set_affinity(irq, affinity);
239 else if (desc->action && !(warned++)) 238 else if (desc->action)
240 printk("Cannot set affinity for irq %i\n", irq); 239 printk_once("Cannot set affinity for irq %i\n", irq);
241 } 240 }
242 241
243#if 0 242#if 0
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index c664d515f613..63b0ec8d3d4a 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -34,7 +34,6 @@
34struct kvm_para_state { 34struct kvm_para_state {
35 u8 mmu_queue[MMU_QUEUE_SIZE]; 35 u8 mmu_queue[MMU_QUEUE_SIZE];
36 int mmu_queue_len; 36 int mmu_queue_len;
37 enum paravirt_lazy_mode mode;
38}; 37};
39 38
40static DEFINE_PER_CPU(struct kvm_para_state, para_state); 39static DEFINE_PER_CPU(struct kvm_para_state, para_state);
@@ -77,7 +76,7 @@ static void kvm_deferred_mmu_op(void *buffer, int len)
77{ 76{
78 struct kvm_para_state *state = kvm_para_state(); 77 struct kvm_para_state *state = kvm_para_state();
79 78
80 if (state->mode != PARAVIRT_LAZY_MMU) { 79 if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) {
81 kvm_mmu_op(buffer, len); 80 kvm_mmu_op(buffer, len);
82 return; 81 return;
83 } 82 }
@@ -185,10 +184,7 @@ static void kvm_release_pt(unsigned long pfn)
185 184
186static void kvm_enter_lazy_mmu(void) 185static void kvm_enter_lazy_mmu(void)
187{ 186{
188 struct kvm_para_state *state = kvm_para_state();
189
190 paravirt_enter_lazy_mmu(); 187 paravirt_enter_lazy_mmu();
191 state->mode = paravirt_get_lazy_mode();
192} 188}
193 189
194static void kvm_leave_lazy_mmu(void) 190static void kvm_leave_lazy_mmu(void)
@@ -197,7 +193,6 @@ static void kvm_leave_lazy_mmu(void)
197 193
198 mmu_queue_flush(state); 194 mmu_queue_flush(state);
199 paravirt_leave_lazy_mmu(); 195 paravirt_leave_lazy_mmu();
200 state->mode = paravirt_get_lazy_mode();
201} 196}
202 197
203static void __init paravirt_ops_setup(void) 198static void __init paravirt_ops_setup(void)
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 223af43f1526..e5efcdcca31b 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -50,8 +50,8 @@ static unsigned long kvm_get_wallclock(void)
50 struct timespec ts; 50 struct timespec ts;
51 int low, high; 51 int low, high;
52 52
53 low = (int)__pa(&wall_clock); 53 low = (int)__pa_symbol(&wall_clock);
54 high = ((u64)__pa(&wall_clock) >> 32); 54 high = ((u64)__pa_symbol(&wall_clock) >> 32);
55 native_write_msr(MSR_KVM_WALL_CLOCK, low, high); 55 native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
56 56
57 vcpu_time = &get_cpu_var(hv_clock); 57 vcpu_time = &get_cpu_var(hv_clock);
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 651c93b28862..fcd513bf2846 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -482,11 +482,11 @@ static void __init construct_ioapic_table(int mpc_default_type)
482 MP_bus_info(&bus); 482 MP_bus_info(&bus);
483 } 483 }
484 484
485 ioapic.type = MP_IOAPIC; 485 ioapic.type = MP_IOAPIC;
486 ioapic.apicid = 2; 486 ioapic.apicid = 2;
487 ioapic.apicver = mpc_default_type > 4 ? 0x10 : 0x01; 487 ioapic.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
488 ioapic.flags = MPC_APIC_USABLE; 488 ioapic.flags = MPC_APIC_USABLE;
489 ioapic.apicaddr = 0xFEC00000; 489 ioapic.apicaddr = IO_APIC_DEFAULT_PHYS_BASE;
490 MP_ioapic_info(&ioapic); 490 MP_ioapic_info(&ioapic);
491 491
492 /* 492 /*
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 98fd6cd4e3a4..7dd950094178 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -1,6 +1,7 @@
1/* ----------------------------------------------------------------------- * 1/* ----------------------------------------------------------------------- *
2 * 2 *
3 * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved 3 * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
4 * Copyright 2009 Intel Corporation; author: H. Peter Anvin
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -80,11 +81,8 @@ static ssize_t msr_read(struct file *file, char __user *buf,
80 81
81 for (; count; count -= 8) { 82 for (; count; count -= 8) {
82 err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); 83 err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
83 if (err) { 84 if (err)
84 if (err == -EFAULT) /* Fix idiotic error code */
85 err = -EIO;
86 break; 85 break;
87 }
88 if (copy_to_user(tmp, &data, 8)) { 86 if (copy_to_user(tmp, &data, 8)) {
89 err = -EFAULT; 87 err = -EFAULT;
90 break; 88 break;
@@ -115,11 +113,8 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
115 break; 113 break;
116 } 114 }
117 err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); 115 err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
118 if (err) { 116 if (err)
119 if (err == -EFAULT) /* Fix idiotic error code */
120 err = -EIO;
121 break; 117 break;
122 }
123 tmp += 2; 118 tmp += 2;
124 bytes += 8; 119 bytes += 8;
125 } 120 }
@@ -127,6 +122,54 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
127 return bytes ? bytes : err; 122 return bytes ? bytes : err;
128} 123}
129 124
125static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
126{
127 u32 __user *uregs = (u32 __user *)arg;
128 u32 regs[8];
129 int cpu = iminor(file->f_path.dentry->d_inode);
130 int err;
131
132 switch (ioc) {
133 case X86_IOC_RDMSR_REGS:
134 if (!(file->f_mode & FMODE_READ)) {
135 err = -EBADF;
136 break;
137 }
138 if (copy_from_user(&regs, uregs, sizeof regs)) {
139 err = -EFAULT;
140 break;
141 }
142 err = rdmsr_safe_regs_on_cpu(cpu, regs);
143 if (err)
144 break;
145 if (copy_to_user(uregs, &regs, sizeof regs))
146 err = -EFAULT;
147 break;
148
149 case X86_IOC_WRMSR_REGS:
150 if (!(file->f_mode & FMODE_WRITE)) {
151 err = -EBADF;
152 break;
153 }
154 if (copy_from_user(&regs, uregs, sizeof regs)) {
155 err = -EFAULT;
156 break;
157 }
158 err = wrmsr_safe_regs_on_cpu(cpu, regs);
159 if (err)
160 break;
161 if (copy_to_user(uregs, &regs, sizeof regs))
162 err = -EFAULT;
163 break;
164
165 default:
166 err = -ENOTTY;
167 break;
168 }
169
170 return err;
171}
172
130static int msr_open(struct inode *inode, struct file *file) 173static int msr_open(struct inode *inode, struct file *file)
131{ 174{
132 unsigned int cpu = iminor(file->f_path.dentry->d_inode); 175 unsigned int cpu = iminor(file->f_path.dentry->d_inode);
@@ -157,6 +200,8 @@ static const struct file_operations msr_fops = {
157 .read = msr_read, 200 .read = msr_read,
158 .write = msr_write, 201 .write = msr_write,
159 .open = msr_open, 202 .open = msr_open,
203 .unlocked_ioctl = msr_ioctl,
204 .compat_ioctl = msr_ioctl,
160}; 205};
161 206
162static int __cpuinit msr_device_create(int cpu) 207static int __cpuinit msr_device_create(int cpu)
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 70ec9b951d76..f5b0b4a01fb2 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -362,8 +362,9 @@ struct pv_cpu_ops pv_cpu_ops = {
362#endif 362#endif
363 .wbinvd = native_wbinvd, 363 .wbinvd = native_wbinvd,
364 .read_msr = native_read_msr_safe, 364 .read_msr = native_read_msr_safe,
365 .read_msr_amd = native_read_msr_amd_safe, 365 .rdmsr_regs = native_rdmsr_safe_regs,
366 .write_msr = native_write_msr_safe, 366 .write_msr = native_write_msr_safe,
367 .wrmsr_regs = native_wrmsr_safe_regs,
367 .read_tsc = native_read_tsc, 368 .read_tsc = native_read_tsc,
368 .read_pmc = native_read_pmc, 369 .read_pmc = native_read_pmc,
369 .read_tscp = native_read_tscp, 370 .read_tscp = native_read_tscp,
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 1a041bcf506b..d71c8655905b 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -3,6 +3,7 @@
3#include <linux/dmar.h> 3#include <linux/dmar.h>
4#include <linux/bootmem.h> 4#include <linux/bootmem.h>
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/kmemleak.h>
6 7
7#include <asm/proto.h> 8#include <asm/proto.h>
8#include <asm/dma.h> 9#include <asm/dma.h>
@@ -32,7 +33,14 @@ int no_iommu __read_mostly;
32/* Set this to 1 if there is a HW IOMMU in the system */ 33/* Set this to 1 if there is a HW IOMMU in the system */
33int iommu_detected __read_mostly = 0; 34int iommu_detected __read_mostly = 0;
34 35
35int iommu_pass_through; 36/*
37 * This variable becomes 1 if iommu=pt is passed on the kernel command line.
38 * If this variable is 1, IOMMU implementations do no DMA ranslation for
39 * devices and allow every device to access to whole physical memory. This is
40 * useful if a user want to use an IOMMU only for KVM device assignment to
41 * guests and not for driver dma translation.
42 */
43int iommu_pass_through __read_mostly;
36 44
37dma_addr_t bad_dma_address __read_mostly = 0; 45dma_addr_t bad_dma_address __read_mostly = 0;
38EXPORT_SYMBOL(bad_dma_address); 46EXPORT_SYMBOL(bad_dma_address);
@@ -88,6 +96,11 @@ void __init dma32_reserve_bootmem(void)
88 size = roundup(dma32_bootmem_size, align); 96 size = roundup(dma32_bootmem_size, align);
89 dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align, 97 dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
90 512ULL<<20); 98 512ULL<<20);
99 /*
100 * Kmemleak should not scan this block as it may not be mapped via the
101 * kernel direct mapping.
102 */
103 kmemleak_ignore(dma32_bootmem_ptr);
91 if (dma32_bootmem_ptr) 104 if (dma32_bootmem_ptr)
92 dma32_bootmem_size = size; 105 dma32_bootmem_size = size;
93 else 106 else
@@ -147,7 +160,7 @@ again:
147 return NULL; 160 return NULL;
148 161
149 addr = page_to_phys(page); 162 addr = page_to_phys(page);
150 if (!is_buffer_dma_capable(dma_mask, addr, size)) { 163 if (addr + size > dma_mask) {
151 __free_pages(page, get_order(size)); 164 __free_pages(page, get_order(size));
152 165
153 if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) { 166 if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) {
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index d2e56b8f48e7..98a827ee9ed7 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -190,14 +190,13 @@ static void iommu_full(struct device *dev, size_t size, int dir)
190static inline int 190static inline int
191need_iommu(struct device *dev, unsigned long addr, size_t size) 191need_iommu(struct device *dev, unsigned long addr, size_t size)
192{ 192{
193 return force_iommu || 193 return force_iommu || !dma_capable(dev, addr, size);
194 !is_buffer_dma_capable(*dev->dma_mask, addr, size);
195} 194}
196 195
197static inline int 196static inline int
198nonforced_iommu(struct device *dev, unsigned long addr, size_t size) 197nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
199{ 198{
200 return !is_buffer_dma_capable(*dev->dma_mask, addr, size); 199 return !dma_capable(dev, addr, size);
201} 200}
202 201
203/* Map a single continuous physical area into the IOMMU. 202/* Map a single continuous physical area into the IOMMU.
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 71d412a09f30..a3933d4330cd 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -14,7 +14,7 @@
14static int 14static int
15check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) 15check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
16{ 16{
17 if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) { 17 if (hwdev && !dma_capable(hwdev, bus, size)) {
18 if (*hwdev->dma_mask >= DMA_BIT_MASK(32)) 18 if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
19 printk(KERN_ERR 19 printk(KERN_ERR
20 "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", 20 "nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
@@ -79,12 +79,29 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
79 free_pages((unsigned long)vaddr, get_order(size)); 79 free_pages((unsigned long)vaddr, get_order(size));
80} 80}
81 81
82static void nommu_sync_single_for_device(struct device *dev,
83 dma_addr_t addr, size_t size,
84 enum dma_data_direction dir)
85{
86 flush_write_buffers();
87}
88
89
90static void nommu_sync_sg_for_device(struct device *dev,
91 struct scatterlist *sg, int nelems,
92 enum dma_data_direction dir)
93{
94 flush_write_buffers();
95}
96
82struct dma_map_ops nommu_dma_ops = { 97struct dma_map_ops nommu_dma_ops = {
83 .alloc_coherent = dma_generic_alloc_coherent, 98 .alloc_coherent = dma_generic_alloc_coherent,
84 .free_coherent = nommu_free_coherent, 99 .free_coherent = nommu_free_coherent,
85 .map_sg = nommu_map_sg, 100 .map_sg = nommu_map_sg,
86 .map_page = nommu_map_page, 101 .map_page = nommu_map_page,
87 .is_phys = 1, 102 .sync_single_for_device = nommu_sync_single_for_device,
103 .sync_sg_for_device = nommu_sync_sg_for_device,
104 .is_phys = 1,
88}; 105};
89 106
90void __init no_iommu_init(void) 107void __init no_iommu_init(void)
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index 6af96ee44200..e8a35016115f 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -13,31 +13,6 @@
13 13
14int swiotlb __read_mostly; 14int swiotlb __read_mostly;
15 15
16void * __init swiotlb_alloc_boot(size_t size, unsigned long nslabs)
17{
18 return alloc_bootmem_low_pages(size);
19}
20
21void *swiotlb_alloc(unsigned order, unsigned long nslabs)
22{
23 return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order);
24}
25
26dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
27{
28 return paddr;
29}
30
31phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
32{
33 return baddr;
34}
35
36int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size)
37{
38 return 0;
39}
40
41static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 16static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
42 dma_addr_t *dma_handle, gfp_t flags) 17 dma_addr_t *dma_handle, gfp_t flags)
43{ 18{
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 00a8fe4c58bb..209e74801763 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -63,9 +63,6 @@
63 63
64asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 64asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
65 65
66DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
67EXPORT_PER_CPU_SYMBOL(current_task);
68
69/* 66/*
70 * Return saved PC of a blocked thread. 67 * Return saved PC of a blocked thread.
71 */ 68 */
@@ -361,14 +358,21 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
361 *next = &next_p->thread; 358 *next = &next_p->thread;
362 int cpu = smp_processor_id(); 359 int cpu = smp_processor_id();
363 struct tss_struct *tss = &per_cpu(init_tss, cpu); 360 struct tss_struct *tss = &per_cpu(init_tss, cpu);
361 bool preload_fpu;
364 362
365 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ 363 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
366 364
367 __unlazy_fpu(prev_p); 365 /*
366 * If the task has used fpu the last 5 timeslices, just do a full
367 * restore of the math state immediately to avoid the trap; the
368 * chances of needing FPU soon are obviously high now
369 */
370 preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
368 371
372 __unlazy_fpu(prev_p);
369 373
370 /* we're going to use this soon, after a few expensive things */ 374 /* we're going to use this soon, after a few expensive things */
371 if (next_p->fpu_counter > 5) 375 if (preload_fpu)
372 prefetch(next->xstate); 376 prefetch(next->xstate);
373 377
374 /* 378 /*
@@ -409,6 +413,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
409 task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) 413 task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
410 __switch_to_xtra(prev_p, next_p, tss); 414 __switch_to_xtra(prev_p, next_p, tss);
411 415
416 /* If we're going to preload the fpu context, make sure clts
417 is run while we're batching the cpu state updates. */
418 if (preload_fpu)
419 clts();
420
412 /* 421 /*
413 * Leave lazy mode, flushing any hypercalls made here. 422 * Leave lazy mode, flushing any hypercalls made here.
414 * This must be done before restoring TLS segments so 423 * This must be done before restoring TLS segments so
@@ -418,15 +427,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
418 */ 427 */
419 arch_end_context_switch(next_p); 428 arch_end_context_switch(next_p);
420 429
421 /* If the task has used fpu the last 5 timeslices, just do a full 430 if (preload_fpu)
422 * restore of the math state immediately to avoid the trap; the 431 __math_state_restore();
423 * chances of needing FPU soon are obviously high now
424 *
425 * tsk_used_math() checks prevent calling math_state_restore(),
426 * which can sleep in the case of !tsk_used_math()
427 */
428 if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
429 math_state_restore();
430 432
431 /* 433 /*
432 * Restore %gs if needed (which is common) 434 * Restore %gs if needed (which is common)
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 89c46f1259d3..72edac026a78 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -57,9 +57,6 @@
57 57
58asmlinkage extern void ret_from_fork(void); 58asmlinkage extern void ret_from_fork(void);
59 59
60DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
61EXPORT_PER_CPU_SYMBOL(current_task);
62
63DEFINE_PER_CPU(unsigned long, old_rsp); 60DEFINE_PER_CPU(unsigned long, old_rsp);
64static DEFINE_PER_CPU(unsigned char, is_idle); 61static DEFINE_PER_CPU(unsigned char, is_idle);
65 62
@@ -399,9 +396,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
399 int cpu = smp_processor_id(); 396 int cpu = smp_processor_id();
400 struct tss_struct *tss = &per_cpu(init_tss, cpu); 397 struct tss_struct *tss = &per_cpu(init_tss, cpu);
401 unsigned fsindex, gsindex; 398 unsigned fsindex, gsindex;
399 bool preload_fpu;
400
401 /*
402 * If the task has used fpu the last 5 timeslices, just do a full
403 * restore of the math state immediately to avoid the trap; the
404 * chances of needing FPU soon are obviously high now
405 */
406 preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
402 407
403 /* we're going to use this soon, after a few expensive things */ 408 /* we're going to use this soon, after a few expensive things */
404 if (next_p->fpu_counter > 5) 409 if (preload_fpu)
405 prefetch(next->xstate); 410 prefetch(next->xstate);
406 411
407 /* 412 /*
@@ -432,6 +437,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
432 437
433 load_TLS(next, cpu); 438 load_TLS(next, cpu);
434 439
440 /* Must be after DS reload */
441 unlazy_fpu(prev_p);
442
443 /* Make sure cpu is ready for new context */
444 if (preload_fpu)
445 clts();
446
435 /* 447 /*
436 * Leave lazy mode, flushing any hypercalls made here. 448 * Leave lazy mode, flushing any hypercalls made here.
437 * This must be done before restoring TLS segments so 449 * This must be done before restoring TLS segments so
@@ -472,9 +484,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
472 wrmsrl(MSR_KERNEL_GS_BASE, next->gs); 484 wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
473 prev->gsindex = gsindex; 485 prev->gsindex = gsindex;
474 486
475 /* Must be after DS reload */
476 unlazy_fpu(prev_p);
477
478 /* 487 /*
479 * Switch the PDA and FPU contexts. 488 * Switch the PDA and FPU contexts.
480 */ 489 */
@@ -493,15 +502,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
493 task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) 502 task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
494 __switch_to_xtra(prev_p, next_p, tss); 503 __switch_to_xtra(prev_p, next_p, tss);
495 504
496 /* If the task has used fpu the last 5 timeslices, just do a full 505 /*
497 * restore of the math state immediately to avoid the trap; the 506 * Preload the FPU context, now that we've determined that the
498 * chances of needing FPU soon are obviously high now 507 * task is likely to be using it.
499 *
500 * tsk_used_math() checks prevent calling math_state_restore(),
501 * which can sleep in the case of !tsk_used_math()
502 */ 508 */
503 if (tsk_used_math(next_p) && next_p->fpu_counter > 5) 509 if (preload_fpu)
504 math_state_restore(); 510 __math_state_restore();
505 /* 511 /*
506 * There's a problem with moving the arch_install_thread_hw_breakpoint() 512 * There's a problem with moving the arch_install_thread_hw_breakpoint()
507 * call before current is updated. Suppose a kernel breakpoint is 513 * call before current is updated. Suppose a kernel breakpoint is
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 0f89a4f20db2..baaf8052f355 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -860,6 +860,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
860 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 860 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
861 clear_thread_flag(TIF_NOTIFY_RESUME); 861 clear_thread_flag(TIF_NOTIFY_RESUME);
862 tracehook_notify_resume(regs); 862 tracehook_notify_resume(regs);
863 if (current->replacement_session_keyring)
864 key_replace_session_keyring();
863 } 865 }
864 866
865#ifdef CONFIG_X86_32 867#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index dee0f3d814af..ec7b64c2df82 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -436,7 +436,8 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
436 * For perf, we return last level cache shared map. 436 * For perf, we return last level cache shared map.
437 * And for power savings, we return cpu_core_map 437 * And for power savings, we return cpu_core_map
438 */ 438 */
439 if (sched_mc_power_savings || sched_smt_power_savings) 439 if ((sched_mc_power_savings || sched_smt_power_savings) &&
440 !(cpu_has(c, X86_FEATURE_AMD_DCM)))
440 return cpu_core_mask(cpu); 441 return cpu_core_mask(cpu);
441 else 442 else
442 return c->llc_shared_map; 443 return c->llc_shared_map;
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index e8b9863ef8c4..3149032ff107 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -4,6 +4,7 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/mm.h> 5#include <linux/mm.h>
6#include <linux/ptrace.h> 6#include <linux/ptrace.h>
7#include <asm/desc.h>
7 8
8unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs) 9unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
9{ 10{
@@ -23,7 +24,7 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
23 * and APM bios ones we just ignore here. 24 * and APM bios ones we just ignore here.
24 */ 25 */
25 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) { 26 if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
26 u32 *desc; 27 struct desc_struct *desc;
27 unsigned long base; 28 unsigned long base;
28 29
29 seg &= ~7UL; 30 seg &= ~7UL;
@@ -33,12 +34,10 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
33 addr = -1L; /* bogus selector, access would fault */ 34 addr = -1L; /* bogus selector, access would fault */
34 else { 35 else {
35 desc = child->mm->context.ldt + seg; 36 desc = child->mm->context.ldt + seg;
36 base = ((desc[0] >> 16) | 37 base = get_desc_base(desc);
37 ((desc[1] & 0xff) << 16) |
38 (desc[1] & 0xff000000));
39 38
40 /* 16-bit code segment? */ 39 /* 16-bit code segment? */
41 if (!((desc[1] >> 22) & 1)) 40 if (!desc->d)
42 addr &= 0xffff; 41 addr &= 0xffff;
43 addr += base; 42 addr += base;
44 } 43 }
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 77b9689f8edb..503c1f2e8835 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -640,13 +640,13 @@ static int __init uv_ptc_init(void)
640 if (!is_uv_system()) 640 if (!is_uv_system())
641 return 0; 641 return 0;
642 642
643 proc_uv_ptc = create_proc_entry(UV_PTC_BASENAME, 0444, NULL); 643 proc_uv_ptc = proc_create(UV_PTC_BASENAME, 0444, NULL,
644 &proc_uv_ptc_operations);
644 if (!proc_uv_ptc) { 645 if (!proc_uv_ptc) {
645 printk(KERN_ERR "unable to create %s proc entry\n", 646 printk(KERN_ERR "unable to create %s proc entry\n",
646 UV_PTC_BASENAME); 647 UV_PTC_BASENAME);
647 return -EINVAL; 648 return -EINVAL;
648 } 649 }
649 proc_uv_ptc->proc_fops = &proc_uv_ptc_operations;
650 return 0; 650 return 0;
651} 651}
652 652
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index ae04589a579b..49a401b1d4d7 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -76,7 +76,7 @@ char ignore_fpu_irq;
76 * F0 0F bug workaround.. We have a special link segment 76 * F0 0F bug workaround.. We have a special link segment
77 * for this. 77 * for this.
78 */ 78 */
79gate_desc idt_table[256] 79gate_desc idt_table[NR_VECTORS]
80 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; 80 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
81#endif 81#endif
82 82
@@ -765,33 +765,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
765#endif 765#endif
766} 766}
767 767
768#ifdef CONFIG_X86_32 768asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
769unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
770{ 769{
771 struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
772 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
773 unsigned long new_kesp = kesp - base;
774 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
775 __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
776
777 /* Set up base for espfix segment */
778 desc &= 0x00f0ff0000000000ULL;
779 desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
780 ((((__u64)base) << 32) & 0xff00000000000000ULL) |
781 ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
782 (lim_pages & 0xffff);
783 *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
784
785 return new_kesp;
786} 770}
787#endif
788 771
789asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) 772asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
790{ 773{
791} 774}
792 775
793asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) 776/*
777 * __math_state_restore assumes that cr0.TS is already clear and the
778 * fpu state is all ready for use. Used during context switch.
779 */
780void __math_state_restore(void)
794{ 781{
782 struct thread_info *thread = current_thread_info();
783 struct task_struct *tsk = thread->task;
784
785 /*
786 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
787 */
788 if (unlikely(restore_fpu_checking(tsk))) {
789 stts();
790 force_sig(SIGSEGV, tsk);
791 return;
792 }
793
794 thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
795 tsk->fpu_counter++;
795} 796}
796 797
797/* 798/*
@@ -825,17 +826,8 @@ asmlinkage void math_state_restore(void)
825 } 826 }
826 827
827 clts(); /* Allow maths ops (or we recurse) */ 828 clts(); /* Allow maths ops (or we recurse) */
828 /*
829 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
830 */
831 if (unlikely(restore_fpu_checking(tsk))) {
832 stts();
833 force_sig(SIGSEGV, tsk);
834 return;
835 }
836 829
837 thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ 830 __math_state_restore();
838 tsk->fpu_counter++;
839} 831}
840EXPORT_SYMBOL_GPL(math_state_restore); 832EXPORT_SYMBOL_GPL(math_state_restore);
841 833
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 8600a09e0c6c..b84e571f4175 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -1,12 +1,8 @@
1# 1#
2# KVM configuration 2# KVM configuration
3# 3#
4config HAVE_KVM
5 bool
6 4
7config HAVE_KVM_IRQCHIP 5source "virt/kvm/Kconfig"
8 bool
9 default y
10 6
11menuconfig VIRTUALIZATION 7menuconfig VIRTUALIZATION
12 bool "Virtualization" 8 bool "Virtualization"
@@ -29,6 +25,9 @@ config KVM
29 select PREEMPT_NOTIFIERS 25 select PREEMPT_NOTIFIERS
30 select MMU_NOTIFIER 26 select MMU_NOTIFIER
31 select ANON_INODES 27 select ANON_INODES
28 select HAVE_KVM_IRQCHIP
29 select HAVE_KVM_EVENTFD
30 select KVM_APIC_ARCHITECTURE
32 ---help--- 31 ---help---
33 Support hosting fully virtualized guest machines using hardware 32 Support hosting fully virtualized guest machines using hardware
34 virtualization extensions. You will need a fairly recent 33 virtualization extensions. You will need a fairly recent
@@ -63,18 +62,6 @@ config KVM_AMD
63 To compile this as a module, choose M here: the module 62 To compile this as a module, choose M here: the module
64 will be called kvm-amd. 63 will be called kvm-amd.
65 64
66config KVM_TRACE
67 bool "KVM trace support"
68 depends on KVM && SYSFS
69 select MARKERS
70 select RELAY
71 select DEBUG_FS
72 default n
73 ---help---
74 This option allows reading a trace of kvm-related events through
75 relayfs. Note the ABI is not considered stable and will be
76 modified in future updates.
77
78# OK, it's a little counter-intuitive to do this, but it puts it neatly under 65# OK, it's a little counter-intuitive to do this, but it puts it neatly under
79# the virtualization menu. 66# the virtualization menu.
80source drivers/lguest/Kconfig 67source drivers/lguest/Kconfig
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index b43c4efafe80..0e7fe78d0f74 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -1,22 +1,19 @@
1#
2# Makefile for Kernel-based Virtual Machine module
3#
4
5common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
6 coalesced_mmio.o irq_comm.o)
7ifeq ($(CONFIG_KVM_TRACE),y)
8common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o)
9endif
10ifeq ($(CONFIG_IOMMU_API),y)
11common-objs += $(addprefix ../../../virt/kvm/, iommu.o)
12endif
13 1
14EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm 2EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm
15 3
16kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o \ 4CFLAGS_x86.o := -I.
17 i8254.o timer.o 5CFLAGS_svm.o := -I.
18obj-$(CONFIG_KVM) += kvm.o 6CFLAGS_vmx.o := -I.
19kvm-intel-objs = vmx.o 7
20obj-$(CONFIG_KVM_INTEL) += kvm-intel.o 8kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
21kvm-amd-objs = svm.o 9 coalesced_mmio.o irq_comm.o eventfd.o)
22obj-$(CONFIG_KVM_AMD) += kvm-amd.o 10kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o)
11
12kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
13 i8254.o timer.o
14kvm-intel-y += vmx.o
15kvm-amd-y += svm.o
16
17obj-$(CONFIG_KVM) += kvm.o
18obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
19obj-$(CONFIG_KVM_AMD) += kvm-amd.o
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/emulate.c
index 616de4628d60..1be5cd640e93 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1,5 +1,5 @@
1/****************************************************************************** 1/******************************************************************************
2 * x86_emulate.c 2 * emulate.c
3 * 3 *
4 * Generic x86 (32-bit and 64-bit) instruction decoder and emulator. 4 * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
5 * 5 *
@@ -30,7 +30,9 @@
30#define DPRINTF(x...) do {} while (0) 30#define DPRINTF(x...) do {} while (0)
31#endif 31#endif
32#include <linux/module.h> 32#include <linux/module.h>
33#include <asm/kvm_x86_emulate.h> 33#include <asm/kvm_emulate.h>
34
35#include "mmu.h" /* for is_long_mode() */
34 36
35/* 37/*
36 * Opcode effective-address decode tables. 38 * Opcode effective-address decode tables.
@@ -60,6 +62,7 @@
60#define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ 62#define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */
61#define SrcOne (7<<4) /* Implied '1' */ 63#define SrcOne (7<<4) /* Implied '1' */
62#define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ 64#define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */
65#define SrcImmU (9<<4) /* Immediate operand, unsigned */
63#define SrcMask (0xf<<4) 66#define SrcMask (0xf<<4)
64/* Generic ModRM decode. */ 67/* Generic ModRM decode. */
65#define ModRM (1<<8) 68#define ModRM (1<<8)
@@ -97,11 +100,11 @@ static u32 opcode_table[256] = {
97 /* 0x10 - 0x17 */ 100 /* 0x10 - 0x17 */
98 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 101 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
99 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 102 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
100 0, 0, 0, 0, 103 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
101 /* 0x18 - 0x1F */ 104 /* 0x18 - 0x1F */
102 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 105 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
103 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 106 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
104 0, 0, 0, 0, 107 ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
105 /* 0x20 - 0x27 */ 108 /* 0x20 - 0x27 */
106 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 109 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
107 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 110 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -195,7 +198,7 @@ static u32 opcode_table[256] = {
195 ByteOp | SrcImmUByte, SrcImmUByte, 198 ByteOp | SrcImmUByte, SrcImmUByte,
196 /* 0xE8 - 0xEF */ 199 /* 0xE8 - 0xEF */
197 SrcImm | Stack, SrcImm | ImplicitOps, 200 SrcImm | Stack, SrcImm | ImplicitOps,
198 SrcImm | Src2Imm16, SrcImmByte | ImplicitOps, 201 SrcImmU | Src2Imm16, SrcImmByte | ImplicitOps,
199 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, 202 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
200 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, 203 SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
201 /* 0xF0 - 0xF7 */ 204 /* 0xF0 - 0xF7 */
@@ -208,7 +211,7 @@ static u32 opcode_table[256] = {
208 211
209static u32 twobyte_table[256] = { 212static u32 twobyte_table[256] = {
210 /* 0x00 - 0x0F */ 213 /* 0x00 - 0x0F */
211 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, 214 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0,
212 ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 215 ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
213 /* 0x10 - 0x1F */ 216 /* 0x10 - 0x1F */
214 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, 217 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
@@ -216,7 +219,9 @@ static u32 twobyte_table[256] = {
216 ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, 219 ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 220 0, 0, 0, 0, 0, 0, 0, 0,
218 /* 0x30 - 0x3F */ 221 /* 0x30 - 0x3F */
219 ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222 ImplicitOps, 0, ImplicitOps, 0,
223 ImplicitOps, ImplicitOps, 0, 0,
224 0, 0, 0, 0, 0, 0, 0, 0,
220 /* 0x40 - 0x47 */ 225 /* 0x40 - 0x47 */
221 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, 226 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
222 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, 227 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
@@ -319,8 +324,11 @@ static u32 group2_table[] = {
319}; 324};
320 325
321/* EFLAGS bit definitions. */ 326/* EFLAGS bit definitions. */
327#define EFLG_VM (1<<17)
328#define EFLG_RF (1<<16)
322#define EFLG_OF (1<<11) 329#define EFLG_OF (1<<11)
323#define EFLG_DF (1<<10) 330#define EFLG_DF (1<<10)
331#define EFLG_IF (1<<9)
324#define EFLG_SF (1<<7) 332#define EFLG_SF (1<<7)
325#define EFLG_ZF (1<<6) 333#define EFLG_ZF (1<<6)
326#define EFLG_AF (1<<4) 334#define EFLG_AF (1<<4)
@@ -1027,6 +1035,7 @@ done_prefixes:
1027 c->src.type = OP_MEM; 1035 c->src.type = OP_MEM;
1028 break; 1036 break;
1029 case SrcImm: 1037 case SrcImm:
1038 case SrcImmU:
1030 c->src.type = OP_IMM; 1039 c->src.type = OP_IMM;
1031 c->src.ptr = (unsigned long *)c->eip; 1040 c->src.ptr = (unsigned long *)c->eip;
1032 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; 1041 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
@@ -1044,6 +1053,19 @@ done_prefixes:
1044 c->src.val = insn_fetch(s32, 4, c->eip); 1053 c->src.val = insn_fetch(s32, 4, c->eip);
1045 break; 1054 break;
1046 } 1055 }
1056 if ((c->d & SrcMask) == SrcImmU) {
1057 switch (c->src.bytes) {
1058 case 1:
1059 c->src.val &= 0xff;
1060 break;
1061 case 2:
1062 c->src.val &= 0xffff;
1063 break;
1064 case 4:
1065 c->src.val &= 0xffffffff;
1066 break;
1067 }
1068 }
1047 break; 1069 break;
1048 case SrcImmByte: 1070 case SrcImmByte:
1049 case SrcImmUByte: 1071 case SrcImmUByte:
@@ -1375,6 +1397,217 @@ static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask)
1375 ctxt->interruptibility = mask; 1397 ctxt->interruptibility = mask;
1376} 1398}
1377 1399
1400static inline void
1401setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
1402 struct kvm_segment *cs, struct kvm_segment *ss)
1403{
1404 memset(cs, 0, sizeof(struct kvm_segment));
1405 kvm_x86_ops->get_segment(ctxt->vcpu, cs, VCPU_SREG_CS);
1406 memset(ss, 0, sizeof(struct kvm_segment));
1407
1408 cs->l = 0; /* will be adjusted later */
1409 cs->base = 0; /* flat segment */
1410 cs->g = 1; /* 4kb granularity */
1411 cs->limit = 0xffffffff; /* 4GB limit */
1412 cs->type = 0x0b; /* Read, Execute, Accessed */
1413 cs->s = 1;
1414 cs->dpl = 0; /* will be adjusted later */
1415 cs->present = 1;
1416 cs->db = 1;
1417
1418 ss->unusable = 0;
1419 ss->base = 0; /* flat segment */
1420 ss->limit = 0xffffffff; /* 4GB limit */
1421 ss->g = 1; /* 4kb granularity */
1422 ss->s = 1;
1423 ss->type = 0x03; /* Read/Write, Accessed */
1424 ss->db = 1; /* 32bit stack segment */
1425 ss->dpl = 0;
1426 ss->present = 1;
1427}
1428
1429static int
1430emulate_syscall(struct x86_emulate_ctxt *ctxt)
1431{
1432 struct decode_cache *c = &ctxt->decode;
1433 struct kvm_segment cs, ss;
1434 u64 msr_data;
1435
1436 /* syscall is not available in real mode */
1437 if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL
1438 || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE))
1439 return -1;
1440
1441 setup_syscalls_segments(ctxt, &cs, &ss);
1442
1443 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
1444 msr_data >>= 32;
1445 cs.selector = (u16)(msr_data & 0xfffc);
1446 ss.selector = (u16)(msr_data + 8);
1447
1448 if (is_long_mode(ctxt->vcpu)) {
1449 cs.db = 0;
1450 cs.l = 1;
1451 }
1452 kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
1453 kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
1454
1455 c->regs[VCPU_REGS_RCX] = c->eip;
1456 if (is_long_mode(ctxt->vcpu)) {
1457#ifdef CONFIG_X86_64
1458 c->regs[VCPU_REGS_R11] = ctxt->eflags & ~EFLG_RF;
1459
1460 kvm_x86_ops->get_msr(ctxt->vcpu,
1461 ctxt->mode == X86EMUL_MODE_PROT64 ?
1462 MSR_LSTAR : MSR_CSTAR, &msr_data);
1463 c->eip = msr_data;
1464
1465 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_SYSCALL_MASK, &msr_data);
1466 ctxt->eflags &= ~(msr_data | EFLG_RF);
1467#endif
1468 } else {
1469 /* legacy mode */
1470 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
1471 c->eip = (u32)msr_data;
1472
1473 ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
1474 }
1475
1476 return 0;
1477}
1478
1479static int
1480emulate_sysenter(struct x86_emulate_ctxt *ctxt)
1481{
1482 struct decode_cache *c = &ctxt->decode;
1483 struct kvm_segment cs, ss;
1484 u64 msr_data;
1485
1486 /* inject #UD if LOCK prefix is used */
1487 if (c->lock_prefix)
1488 return -1;
1489
1490 /* inject #GP if in real mode or paging is disabled */
1491 if (ctxt->mode == X86EMUL_MODE_REAL ||
1492 !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
1493 kvm_inject_gp(ctxt->vcpu, 0);
1494 return -1;
1495 }
1496
1497 /* XXX sysenter/sysexit have not been tested in 64bit mode.
1498 * Therefore, we inject an #UD.
1499 */
1500 if (ctxt->mode == X86EMUL_MODE_PROT64)
1501 return -1;
1502
1503 setup_syscalls_segments(ctxt, &cs, &ss);
1504
1505 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
1506 switch (ctxt->mode) {
1507 case X86EMUL_MODE_PROT32:
1508 if ((msr_data & 0xfffc) == 0x0) {
1509 kvm_inject_gp(ctxt->vcpu, 0);
1510 return -1;
1511 }
1512 break;
1513 case X86EMUL_MODE_PROT64:
1514 if (msr_data == 0x0) {
1515 kvm_inject_gp(ctxt->vcpu, 0);
1516 return -1;
1517 }
1518 break;
1519 }
1520
1521 ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
1522 cs.selector = (u16)msr_data;
1523 cs.selector &= ~SELECTOR_RPL_MASK;
1524 ss.selector = cs.selector + 8;
1525 ss.selector &= ~SELECTOR_RPL_MASK;
1526 if (ctxt->mode == X86EMUL_MODE_PROT64
1527 || is_long_mode(ctxt->vcpu)) {
1528 cs.db = 0;
1529 cs.l = 1;
1530 }
1531
1532 kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
1533 kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
1534
1535 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_EIP, &msr_data);
1536 c->eip = msr_data;
1537
1538 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data);
1539 c->regs[VCPU_REGS_RSP] = msr_data;
1540
1541 return 0;
1542}
1543
1544static int
1545emulate_sysexit(struct x86_emulate_ctxt *ctxt)
1546{
1547 struct decode_cache *c = &ctxt->decode;
1548 struct kvm_segment cs, ss;
1549 u64 msr_data;
1550 int usermode;
1551
1552 /* inject #UD if LOCK prefix is used */
1553 if (c->lock_prefix)
1554 return -1;
1555
1556 /* inject #GP if in real mode or paging is disabled */
1557 if (ctxt->mode == X86EMUL_MODE_REAL
1558 || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
1559 kvm_inject_gp(ctxt->vcpu, 0);
1560 return -1;
1561 }
1562
1563 /* sysexit must be called from CPL 0 */
1564 if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) {
1565 kvm_inject_gp(ctxt->vcpu, 0);
1566 return -1;
1567 }
1568
1569 setup_syscalls_segments(ctxt, &cs, &ss);
1570
1571 if ((c->rex_prefix & 0x8) != 0x0)
1572 usermode = X86EMUL_MODE_PROT64;
1573 else
1574 usermode = X86EMUL_MODE_PROT32;
1575
1576 cs.dpl = 3;
1577 ss.dpl = 3;
1578 kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
1579 switch (usermode) {
1580 case X86EMUL_MODE_PROT32:
1581 cs.selector = (u16)(msr_data + 16);
1582 if ((msr_data & 0xfffc) == 0x0) {
1583 kvm_inject_gp(ctxt->vcpu, 0);
1584 return -1;
1585 }
1586 ss.selector = (u16)(msr_data + 24);
1587 break;
1588 case X86EMUL_MODE_PROT64:
1589 cs.selector = (u16)(msr_data + 32);
1590 if (msr_data == 0x0) {
1591 kvm_inject_gp(ctxt->vcpu, 0);
1592 return -1;
1593 }
1594 ss.selector = cs.selector + 8;
1595 cs.db = 0;
1596 cs.l = 1;
1597 break;
1598 }
1599 cs.selector |= SELECTOR_RPL_MASK;
1600 ss.selector |= SELECTOR_RPL_MASK;
1601
1602 kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
1603 kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
1604
1605 c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX];
1606 c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX];
1607
1608 return 0;
1609}
1610
1378int 1611int
1379x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) 1612x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1380{ 1613{
@@ -1970,6 +2203,12 @@ twobyte_insn:
1970 goto cannot_emulate; 2203 goto cannot_emulate;
1971 } 2204 }
1972 break; 2205 break;
2206 case 0x05: /* syscall */
2207 if (emulate_syscall(ctxt) == -1)
2208 goto cannot_emulate;
2209 else
2210 goto writeback;
2211 break;
1973 case 0x06: 2212 case 0x06:
1974 emulate_clts(ctxt->vcpu); 2213 emulate_clts(ctxt->vcpu);
1975 c->dst.type = OP_NONE; 2214 c->dst.type = OP_NONE;
@@ -2036,6 +2275,18 @@ twobyte_insn:
2036 rc = X86EMUL_CONTINUE; 2275 rc = X86EMUL_CONTINUE;
2037 c->dst.type = OP_NONE; 2276 c->dst.type = OP_NONE;
2038 break; 2277 break;
2278 case 0x34: /* sysenter */
2279 if (emulate_sysenter(ctxt) == -1)
2280 goto cannot_emulate;
2281 else
2282 goto writeback;
2283 break;
2284 case 0x35: /* sysexit */
2285 if (emulate_sysexit(ctxt) == -1)
2286 goto cannot_emulate;
2287 else
2288 goto writeback;
2289 break;
2039 case 0x40 ... 0x4f: /* cmov */ 2290 case 0x40 ... 0x4f: /* cmov */
2040 c->dst.val = c->dst.orig_val = c->src.val; 2291 c->dst.val = c->dst.orig_val = c->src.val;
2041 if (!test_cc(c->b, ctxt->eflags)) 2292 if (!test_cc(c->b, ctxt->eflags))
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 21f68e00524f..82ad523b4901 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -231,7 +231,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu)
231{ 231{
232 struct kvm_pit *pit = vcpu->kvm->arch.vpit; 232 struct kvm_pit *pit = vcpu->kvm->arch.vpit;
233 233
234 if (pit && vcpu->vcpu_id == 0 && pit->pit_state.irq_ack) 234 if (pit && kvm_vcpu_is_bsp(vcpu) && pit->pit_state.irq_ack)
235 return atomic_read(&pit->pit_state.pit_timer.pending); 235 return atomic_read(&pit->pit_state.pit_timer.pending);
236 return 0; 236 return 0;
237} 237}
@@ -252,7 +252,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
252 struct kvm_pit *pit = vcpu->kvm->arch.vpit; 252 struct kvm_pit *pit = vcpu->kvm->arch.vpit;
253 struct hrtimer *timer; 253 struct hrtimer *timer;
254 254
255 if (vcpu->vcpu_id != 0 || !pit) 255 if (!kvm_vcpu_is_bsp(vcpu) || !pit)
256 return; 256 return;
257 257
258 timer = &pit->pit_state.pit_timer.timer; 258 timer = &pit->pit_state.pit_timer.timer;
@@ -294,7 +294,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
294 pt->timer.function = kvm_timer_fn; 294 pt->timer.function = kvm_timer_fn;
295 pt->t_ops = &kpit_ops; 295 pt->t_ops = &kpit_ops;
296 pt->kvm = ps->pit->kvm; 296 pt->kvm = ps->pit->kvm;
297 pt->vcpu_id = 0; 297 pt->vcpu = pt->kvm->bsp_vcpu;
298 298
299 atomic_set(&pt->pending, 0); 299 atomic_set(&pt->pending, 0);
300 ps->irq_ack = 1; 300 ps->irq_ack = 1;
@@ -332,33 +332,62 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
332 case 1: 332 case 1:
333 /* FIXME: enhance mode 4 precision */ 333 /* FIXME: enhance mode 4 precision */
334 case 4: 334 case 4:
335 create_pit_timer(ps, val, 0); 335 if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)) {
336 create_pit_timer(ps, val, 0);
337 }
336 break; 338 break;
337 case 2: 339 case 2:
338 case 3: 340 case 3:
339 create_pit_timer(ps, val, 1); 341 if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)){
342 create_pit_timer(ps, val, 1);
343 }
340 break; 344 break;
341 default: 345 default:
342 destroy_pit_timer(&ps->pit_timer); 346 destroy_pit_timer(&ps->pit_timer);
343 } 347 }
344} 348}
345 349
346void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val) 350void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start)
351{
352 u8 saved_mode;
353 if (hpet_legacy_start) {
354 /* save existing mode for later reenablement */
355 saved_mode = kvm->arch.vpit->pit_state.channels[0].mode;
356 kvm->arch.vpit->pit_state.channels[0].mode = 0xff; /* disable timer */
357 pit_load_count(kvm, channel, val);
358 kvm->arch.vpit->pit_state.channels[0].mode = saved_mode;
359 } else {
360 pit_load_count(kvm, channel, val);
361 }
362}
363
364static inline struct kvm_pit *dev_to_pit(struct kvm_io_device *dev)
365{
366 return container_of(dev, struct kvm_pit, dev);
367}
368
369static inline struct kvm_pit *speaker_to_pit(struct kvm_io_device *dev)
347{ 370{
348 mutex_lock(&kvm->arch.vpit->pit_state.lock); 371 return container_of(dev, struct kvm_pit, speaker_dev);
349 pit_load_count(kvm, channel, val);
350 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
351} 372}
352 373
353static void pit_ioport_write(struct kvm_io_device *this, 374static inline int pit_in_range(gpa_t addr)
354 gpa_t addr, int len, const void *data)
355{ 375{
356 struct kvm_pit *pit = (struct kvm_pit *)this->private; 376 return ((addr >= KVM_PIT_BASE_ADDRESS) &&
377 (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
378}
379
380static int pit_ioport_write(struct kvm_io_device *this,
381 gpa_t addr, int len, const void *data)
382{
383 struct kvm_pit *pit = dev_to_pit(this);
357 struct kvm_kpit_state *pit_state = &pit->pit_state; 384 struct kvm_kpit_state *pit_state = &pit->pit_state;
358 struct kvm *kvm = pit->kvm; 385 struct kvm *kvm = pit->kvm;
359 int channel, access; 386 int channel, access;
360 struct kvm_kpit_channel_state *s; 387 struct kvm_kpit_channel_state *s;
361 u32 val = *(u32 *) data; 388 u32 val = *(u32 *) data;
389 if (!pit_in_range(addr))
390 return -EOPNOTSUPP;
362 391
363 val &= 0xff; 392 val &= 0xff;
364 addr &= KVM_PIT_CHANNEL_MASK; 393 addr &= KVM_PIT_CHANNEL_MASK;
@@ -421,16 +450,19 @@ static void pit_ioport_write(struct kvm_io_device *this,
421 } 450 }
422 451
423 mutex_unlock(&pit_state->lock); 452 mutex_unlock(&pit_state->lock);
453 return 0;
424} 454}
425 455
426static void pit_ioport_read(struct kvm_io_device *this, 456static int pit_ioport_read(struct kvm_io_device *this,
427 gpa_t addr, int len, void *data) 457 gpa_t addr, int len, void *data)
428{ 458{
429 struct kvm_pit *pit = (struct kvm_pit *)this->private; 459 struct kvm_pit *pit = dev_to_pit(this);
430 struct kvm_kpit_state *pit_state = &pit->pit_state; 460 struct kvm_kpit_state *pit_state = &pit->pit_state;
431 struct kvm *kvm = pit->kvm; 461 struct kvm *kvm = pit->kvm;
432 int ret, count; 462 int ret, count;
433 struct kvm_kpit_channel_state *s; 463 struct kvm_kpit_channel_state *s;
464 if (!pit_in_range(addr))
465 return -EOPNOTSUPP;
434 466
435 addr &= KVM_PIT_CHANNEL_MASK; 467 addr &= KVM_PIT_CHANNEL_MASK;
436 s = &pit_state->channels[addr]; 468 s = &pit_state->channels[addr];
@@ -485,37 +517,36 @@ static void pit_ioport_read(struct kvm_io_device *this,
485 memcpy(data, (char *)&ret, len); 517 memcpy(data, (char *)&ret, len);
486 518
487 mutex_unlock(&pit_state->lock); 519 mutex_unlock(&pit_state->lock);
520 return 0;
488} 521}
489 522
490static int pit_in_range(struct kvm_io_device *this, gpa_t addr, 523static int speaker_ioport_write(struct kvm_io_device *this,
491 int len, int is_write) 524 gpa_t addr, int len, const void *data)
492{
493 return ((addr >= KVM_PIT_BASE_ADDRESS) &&
494 (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
495}
496
497static void speaker_ioport_write(struct kvm_io_device *this,
498 gpa_t addr, int len, const void *data)
499{ 525{
500 struct kvm_pit *pit = (struct kvm_pit *)this->private; 526 struct kvm_pit *pit = speaker_to_pit(this);
501 struct kvm_kpit_state *pit_state = &pit->pit_state; 527 struct kvm_kpit_state *pit_state = &pit->pit_state;
502 struct kvm *kvm = pit->kvm; 528 struct kvm *kvm = pit->kvm;
503 u32 val = *(u32 *) data; 529 u32 val = *(u32 *) data;
530 if (addr != KVM_SPEAKER_BASE_ADDRESS)
531 return -EOPNOTSUPP;
504 532
505 mutex_lock(&pit_state->lock); 533 mutex_lock(&pit_state->lock);
506 pit_state->speaker_data_on = (val >> 1) & 1; 534 pit_state->speaker_data_on = (val >> 1) & 1;
507 pit_set_gate(kvm, 2, val & 1); 535 pit_set_gate(kvm, 2, val & 1);
508 mutex_unlock(&pit_state->lock); 536 mutex_unlock(&pit_state->lock);
537 return 0;
509} 538}
510 539
511static void speaker_ioport_read(struct kvm_io_device *this, 540static int speaker_ioport_read(struct kvm_io_device *this,
512 gpa_t addr, int len, void *data) 541 gpa_t addr, int len, void *data)
513{ 542{
514 struct kvm_pit *pit = (struct kvm_pit *)this->private; 543 struct kvm_pit *pit = speaker_to_pit(this);
515 struct kvm_kpit_state *pit_state = &pit->pit_state; 544 struct kvm_kpit_state *pit_state = &pit->pit_state;
516 struct kvm *kvm = pit->kvm; 545 struct kvm *kvm = pit->kvm;
517 unsigned int refresh_clock; 546 unsigned int refresh_clock;
518 int ret; 547 int ret;
548 if (addr != KVM_SPEAKER_BASE_ADDRESS)
549 return -EOPNOTSUPP;
519 550
520 /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */ 551 /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
521 refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1; 552 refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1;
@@ -527,12 +558,7 @@ static void speaker_ioport_read(struct kvm_io_device *this,
527 len = sizeof(ret); 558 len = sizeof(ret);
528 memcpy(data, (char *)&ret, len); 559 memcpy(data, (char *)&ret, len);
529 mutex_unlock(&pit_state->lock); 560 mutex_unlock(&pit_state->lock);
530} 561 return 0;
531
532static int speaker_in_range(struct kvm_io_device *this, gpa_t addr,
533 int len, int is_write)
534{
535 return (addr == KVM_SPEAKER_BASE_ADDRESS);
536} 562}
537 563
538void kvm_pit_reset(struct kvm_pit *pit) 564void kvm_pit_reset(struct kvm_pit *pit)
@@ -541,6 +567,7 @@ void kvm_pit_reset(struct kvm_pit *pit)
541 struct kvm_kpit_channel_state *c; 567 struct kvm_kpit_channel_state *c;
542 568
543 mutex_lock(&pit->pit_state.lock); 569 mutex_lock(&pit->pit_state.lock);
570 pit->pit_state.flags = 0;
544 for (i = 0; i < 3; i++) { 571 for (i = 0; i < 3; i++) {
545 c = &pit->pit_state.channels[i]; 572 c = &pit->pit_state.channels[i];
546 c->mode = 0xff; 573 c->mode = 0xff;
@@ -563,10 +590,22 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
563 } 590 }
564} 591}
565 592
566struct kvm_pit *kvm_create_pit(struct kvm *kvm) 593static const struct kvm_io_device_ops pit_dev_ops = {
594 .read = pit_ioport_read,
595 .write = pit_ioport_write,
596};
597
598static const struct kvm_io_device_ops speaker_dev_ops = {
599 .read = speaker_ioport_read,
600 .write = speaker_ioport_write,
601};
602
603/* Caller must have writers lock on slots_lock */
604struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
567{ 605{
568 struct kvm_pit *pit; 606 struct kvm_pit *pit;
569 struct kvm_kpit_state *pit_state; 607 struct kvm_kpit_state *pit_state;
608 int ret;
570 609
571 pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL); 610 pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
572 if (!pit) 611 if (!pit)
@@ -582,19 +621,6 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
582 mutex_lock(&pit->pit_state.lock); 621 mutex_lock(&pit->pit_state.lock);
583 spin_lock_init(&pit->pit_state.inject_lock); 622 spin_lock_init(&pit->pit_state.inject_lock);
584 623
585 /* Initialize PIO device */
586 pit->dev.read = pit_ioport_read;
587 pit->dev.write = pit_ioport_write;
588 pit->dev.in_range = pit_in_range;
589 pit->dev.private = pit;
590 kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
591
592 pit->speaker_dev.read = speaker_ioport_read;
593 pit->speaker_dev.write = speaker_ioport_write;
594 pit->speaker_dev.in_range = speaker_in_range;
595 pit->speaker_dev.private = pit;
596 kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev);
597
598 kvm->arch.vpit = pit; 624 kvm->arch.vpit = pit;
599 pit->kvm = kvm; 625 pit->kvm = kvm;
600 626
@@ -613,7 +639,30 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
613 pit->mask_notifier.func = pit_mask_notifer; 639 pit->mask_notifier.func = pit_mask_notifer;
614 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); 640 kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
615 641
642 kvm_iodevice_init(&pit->dev, &pit_dev_ops);
643 ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
644 if (ret < 0)
645 goto fail;
646
647 if (flags & KVM_PIT_SPEAKER_DUMMY) {
648 kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
649 ret = __kvm_io_bus_register_dev(&kvm->pio_bus,
650 &pit->speaker_dev);
651 if (ret < 0)
652 goto fail_unregister;
653 }
654
616 return pit; 655 return pit;
656
657fail_unregister:
658 __kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev);
659
660fail:
661 if (pit->irq_source_id >= 0)
662 kvm_free_irq_source_id(kvm, pit->irq_source_id);
663
664 kfree(pit);
665 return NULL;
617} 666}
618 667
619void kvm_free_pit(struct kvm *kvm) 668void kvm_free_pit(struct kvm *kvm)
@@ -623,6 +672,8 @@ void kvm_free_pit(struct kvm *kvm)
623 if (kvm->arch.vpit) { 672 if (kvm->arch.vpit) {
624 kvm_unregister_irq_mask_notifier(kvm, 0, 673 kvm_unregister_irq_mask_notifier(kvm, 0,
625 &kvm->arch.vpit->mask_notifier); 674 &kvm->arch.vpit->mask_notifier);
675 kvm_unregister_irq_ack_notifier(kvm,
676 &kvm->arch.vpit->pit_state.irq_ack_notifier);
626 mutex_lock(&kvm->arch.vpit->pit_state.lock); 677 mutex_lock(&kvm->arch.vpit->pit_state.lock);
627 timer = &kvm->arch.vpit->pit_state.pit_timer.timer; 678 timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
628 hrtimer_cancel(timer); 679 hrtimer_cancel(timer);
@@ -637,10 +688,10 @@ static void __inject_pit_timer_intr(struct kvm *kvm)
637 struct kvm_vcpu *vcpu; 688 struct kvm_vcpu *vcpu;
638 int i; 689 int i;
639 690
640 mutex_lock(&kvm->lock); 691 mutex_lock(&kvm->irq_lock);
641 kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1); 692 kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
642 kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0); 693 kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
643 mutex_unlock(&kvm->lock); 694 mutex_unlock(&kvm->irq_lock);
644 695
645 /* 696 /*
646 * Provides NMI watchdog support via Virtual Wire mode. 697 * Provides NMI watchdog support via Virtual Wire mode.
@@ -652,11 +703,8 @@ static void __inject_pit_timer_intr(struct kvm *kvm)
652 * VCPU0, and only if its LVT0 is in EXTINT mode. 703 * VCPU0, and only if its LVT0 is in EXTINT mode.
653 */ 704 */
654 if (kvm->arch.vapics_in_nmi_mode > 0) 705 if (kvm->arch.vapics_in_nmi_mode > 0)
655 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 706 kvm_for_each_vcpu(i, vcpu, kvm)
656 vcpu = kvm->vcpus[i]; 707 kvm_apic_nmi_wd_deliver(vcpu);
657 if (vcpu)
658 kvm_apic_nmi_wd_deliver(vcpu);
659 }
660} 708}
661 709
662void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu) 710void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
@@ -665,7 +713,7 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
665 struct kvm *kvm = vcpu->kvm; 713 struct kvm *kvm = vcpu->kvm;
666 struct kvm_kpit_state *ps; 714 struct kvm_kpit_state *ps;
667 715
668 if (vcpu && pit) { 716 if (pit) {
669 int inject = 0; 717 int inject = 0;
670 ps = &pit->pit_state; 718 ps = &pit->pit_state;
671 719
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index bbd863ff60b7..d4c1c7ffdc09 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -21,6 +21,7 @@ struct kvm_kpit_channel_state {
21 21
22struct kvm_kpit_state { 22struct kvm_kpit_state {
23 struct kvm_kpit_channel_state channels[3]; 23 struct kvm_kpit_channel_state channels[3];
24 u32 flags;
24 struct kvm_timer pit_timer; 25 struct kvm_timer pit_timer;
25 bool is_periodic; 26 bool is_periodic;
26 u32 speaker_data_on; 27 u32 speaker_data_on;
@@ -49,8 +50,8 @@ struct kvm_pit {
49#define KVM_PIT_CHANNEL_MASK 0x3 50#define KVM_PIT_CHANNEL_MASK 0x3
50 51
51void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); 52void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
52void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val); 53void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start);
53struct kvm_pit *kvm_create_pit(struct kvm *kvm); 54struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags);
54void kvm_free_pit(struct kvm *kvm); 55void kvm_free_pit(struct kvm *kvm);
55void kvm_pit_reset(struct kvm_pit *pit); 56void kvm_pit_reset(struct kvm_pit *pit);
56 57
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 1ccb50c74f18..01f151682802 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -30,50 +30,24 @@
30#include "irq.h" 30#include "irq.h"
31 31
32#include <linux/kvm_host.h> 32#include <linux/kvm_host.h>
33 33#include "trace.h"
34static void pic_lock(struct kvm_pic *s)
35 __acquires(&s->lock)
36{
37 spin_lock(&s->lock);
38}
39
40static void pic_unlock(struct kvm_pic *s)
41 __releases(&s->lock)
42{
43 struct kvm *kvm = s->kvm;
44 unsigned acks = s->pending_acks;
45 bool wakeup = s->wakeup_needed;
46 struct kvm_vcpu *vcpu;
47
48 s->pending_acks = 0;
49 s->wakeup_needed = false;
50
51 spin_unlock(&s->lock);
52
53 while (acks) {
54 kvm_notify_acked_irq(kvm, SELECT_PIC(__ffs(acks)),
55 __ffs(acks));
56 acks &= acks - 1;
57 }
58
59 if (wakeup) {
60 vcpu = s->kvm->vcpus[0];
61 if (vcpu)
62 kvm_vcpu_kick(vcpu);
63 }
64}
65 34
66static void pic_clear_isr(struct kvm_kpic_state *s, int irq) 35static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
67{ 36{
68 s->isr &= ~(1 << irq); 37 s->isr &= ~(1 << irq);
69 s->isr_ack |= (1 << irq); 38 s->isr_ack |= (1 << irq);
39 if (s != &s->pics_state->pics[0])
40 irq += 8;
41 kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
70} 42}
71 43
72void kvm_pic_clear_isr_ack(struct kvm *kvm) 44void kvm_pic_clear_isr_ack(struct kvm *kvm)
73{ 45{
74 struct kvm_pic *s = pic_irqchip(kvm); 46 struct kvm_pic *s = pic_irqchip(kvm);
47 spin_lock(&s->lock);
75 s->pics[0].isr_ack = 0xff; 48 s->pics[0].isr_ack = 0xff;
76 s->pics[1].isr_ack = 0xff; 49 s->pics[1].isr_ack = 0xff;
50 spin_unlock(&s->lock);
77} 51}
78 52
79/* 53/*
@@ -174,9 +148,9 @@ static void pic_update_irq(struct kvm_pic *s)
174 148
175void kvm_pic_update_irq(struct kvm_pic *s) 149void kvm_pic_update_irq(struct kvm_pic *s)
176{ 150{
177 pic_lock(s); 151 spin_lock(&s->lock);
178 pic_update_irq(s); 152 pic_update_irq(s);
179 pic_unlock(s); 153 spin_unlock(&s->lock);
180} 154}
181 155
182int kvm_pic_set_irq(void *opaque, int irq, int level) 156int kvm_pic_set_irq(void *opaque, int irq, int level)
@@ -184,12 +158,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level)
184 struct kvm_pic *s = opaque; 158 struct kvm_pic *s = opaque;
185 int ret = -1; 159 int ret = -1;
186 160
187 pic_lock(s); 161 spin_lock(&s->lock);
188 if (irq >= 0 && irq < PIC_NUM_PINS) { 162 if (irq >= 0 && irq < PIC_NUM_PINS) {
189 ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); 163 ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
190 pic_update_irq(s); 164 pic_update_irq(s);
165 trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
166 s->pics[irq >> 3].imr, ret == 0);
191 } 167 }
192 pic_unlock(s); 168 spin_unlock(&s->lock);
193 169
194 return ret; 170 return ret;
195} 171}
@@ -217,7 +193,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
217 int irq, irq2, intno; 193 int irq, irq2, intno;
218 struct kvm_pic *s = pic_irqchip(kvm); 194 struct kvm_pic *s = pic_irqchip(kvm);
219 195
220 pic_lock(s); 196 spin_lock(&s->lock);
221 irq = pic_get_irq(&s->pics[0]); 197 irq = pic_get_irq(&s->pics[0]);
222 if (irq >= 0) { 198 if (irq >= 0) {
223 pic_intack(&s->pics[0], irq); 199 pic_intack(&s->pics[0], irq);
@@ -242,8 +218,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
242 intno = s->pics[0].irq_base + irq; 218 intno = s->pics[0].irq_base + irq;
243 } 219 }
244 pic_update_irq(s); 220 pic_update_irq(s);
245 pic_unlock(s); 221 spin_unlock(&s->lock);
246 kvm_notify_acked_irq(kvm, SELECT_PIC(irq), irq);
247 222
248 return intno; 223 return intno;
249} 224}
@@ -252,7 +227,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
252{ 227{
253 int irq, irqbase, n; 228 int irq, irqbase, n;
254 struct kvm *kvm = s->pics_state->irq_request_opaque; 229 struct kvm *kvm = s->pics_state->irq_request_opaque;
255 struct kvm_vcpu *vcpu0 = kvm->vcpus[0]; 230 struct kvm_vcpu *vcpu0 = kvm->bsp_vcpu;
256 231
257 if (s == &s->pics_state->pics[0]) 232 if (s == &s->pics_state->pics[0])
258 irqbase = 0; 233 irqbase = 0;
@@ -263,7 +238,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
263 if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0)) 238 if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0))
264 if (s->irr & (1 << irq) || s->isr & (1 << irq)) { 239 if (s->irr & (1 << irq) || s->isr & (1 << irq)) {
265 n = irq + irqbase; 240 n = irq + irqbase;
266 s->pics_state->pending_acks |= 1 << n; 241 kvm_notify_acked_irq(kvm, SELECT_PIC(n), n);
267 } 242 }
268 } 243 }
269 s->last_irr = 0; 244 s->last_irr = 0;
@@ -428,8 +403,7 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1)
428 return s->elcr; 403 return s->elcr;
429} 404}
430 405
431static int picdev_in_range(struct kvm_io_device *this, gpa_t addr, 406static int picdev_in_range(gpa_t addr)
432 int len, int is_write)
433{ 407{
434 switch (addr) { 408 switch (addr) {
435 case 0x20: 409 case 0x20:
@@ -444,18 +418,25 @@ static int picdev_in_range(struct kvm_io_device *this, gpa_t addr,
444 } 418 }
445} 419}
446 420
447static void picdev_write(struct kvm_io_device *this, 421static inline struct kvm_pic *to_pic(struct kvm_io_device *dev)
422{
423 return container_of(dev, struct kvm_pic, dev);
424}
425
426static int picdev_write(struct kvm_io_device *this,
448 gpa_t addr, int len, const void *val) 427 gpa_t addr, int len, const void *val)
449{ 428{
450 struct kvm_pic *s = this->private; 429 struct kvm_pic *s = to_pic(this);
451 unsigned char data = *(unsigned char *)val; 430 unsigned char data = *(unsigned char *)val;
431 if (!picdev_in_range(addr))
432 return -EOPNOTSUPP;
452 433
453 if (len != 1) { 434 if (len != 1) {
454 if (printk_ratelimit()) 435 if (printk_ratelimit())
455 printk(KERN_ERR "PIC: non byte write\n"); 436 printk(KERN_ERR "PIC: non byte write\n");
456 return; 437 return 0;
457 } 438 }
458 pic_lock(s); 439 spin_lock(&s->lock);
459 switch (addr) { 440 switch (addr) {
460 case 0x20: 441 case 0x20:
461 case 0x21: 442 case 0x21:
@@ -468,21 +449,24 @@ static void picdev_write(struct kvm_io_device *this,
468 elcr_ioport_write(&s->pics[addr & 1], addr, data); 449 elcr_ioport_write(&s->pics[addr & 1], addr, data);
469 break; 450 break;
470 } 451 }
471 pic_unlock(s); 452 spin_unlock(&s->lock);
453 return 0;
472} 454}
473 455
474static void picdev_read(struct kvm_io_device *this, 456static int picdev_read(struct kvm_io_device *this,
475 gpa_t addr, int len, void *val) 457 gpa_t addr, int len, void *val)
476{ 458{
477 struct kvm_pic *s = this->private; 459 struct kvm_pic *s = to_pic(this);
478 unsigned char data = 0; 460 unsigned char data = 0;
461 if (!picdev_in_range(addr))
462 return -EOPNOTSUPP;
479 463
480 if (len != 1) { 464 if (len != 1) {
481 if (printk_ratelimit()) 465 if (printk_ratelimit())
482 printk(KERN_ERR "PIC: non byte read\n"); 466 printk(KERN_ERR "PIC: non byte read\n");
483 return; 467 return 0;
484 } 468 }
485 pic_lock(s); 469 spin_lock(&s->lock);
486 switch (addr) { 470 switch (addr) {
487 case 0x20: 471 case 0x20:
488 case 0x21: 472 case 0x21:
@@ -496,7 +480,8 @@ static void picdev_read(struct kvm_io_device *this,
496 break; 480 break;
497 } 481 }
498 *(unsigned char *)val = data; 482 *(unsigned char *)val = data;
499 pic_unlock(s); 483 spin_unlock(&s->lock);
484 return 0;
500} 485}
501 486
502/* 487/*
@@ -505,20 +490,27 @@ static void picdev_read(struct kvm_io_device *this,
505static void pic_irq_request(void *opaque, int level) 490static void pic_irq_request(void *opaque, int level)
506{ 491{
507 struct kvm *kvm = opaque; 492 struct kvm *kvm = opaque;
508 struct kvm_vcpu *vcpu = kvm->vcpus[0]; 493 struct kvm_vcpu *vcpu = kvm->bsp_vcpu;
509 struct kvm_pic *s = pic_irqchip(kvm); 494 struct kvm_pic *s = pic_irqchip(kvm);
510 int irq = pic_get_irq(&s->pics[0]); 495 int irq = pic_get_irq(&s->pics[0]);
511 496
512 s->output = level; 497 s->output = level;
513 if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { 498 if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) {
514 s->pics[0].isr_ack &= ~(1 << irq); 499 s->pics[0].isr_ack &= ~(1 << irq);
515 s->wakeup_needed = true; 500 kvm_vcpu_kick(vcpu);
516 } 501 }
517} 502}
518 503
504static const struct kvm_io_device_ops picdev_ops = {
505 .read = picdev_read,
506 .write = picdev_write,
507};
508
519struct kvm_pic *kvm_create_pic(struct kvm *kvm) 509struct kvm_pic *kvm_create_pic(struct kvm *kvm)
520{ 510{
521 struct kvm_pic *s; 511 struct kvm_pic *s;
512 int ret;
513
522 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); 514 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
523 if (!s) 515 if (!s)
524 return NULL; 516 return NULL;
@@ -534,10 +526,12 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
534 /* 526 /*
535 * Initialize PIO device 527 * Initialize PIO device
536 */ 528 */
537 s->dev.read = picdev_read; 529 kvm_iodevice_init(&s->dev, &picdev_ops);
538 s->dev.write = picdev_write; 530 ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev);
539 s->dev.in_range = picdev_in_range; 531 if (ret < 0) {
540 s->dev.private = s; 532 kfree(s);
541 kvm_io_bus_register_dev(&kvm->pio_bus, &s->dev); 533 return NULL;
534 }
535
542 return s; 536 return s;
543} 537}
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 9f593188129e..7d6058a2fd38 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -63,7 +63,6 @@ struct kvm_kpic_state {
63 63
64struct kvm_pic { 64struct kvm_pic {
65 spinlock_t lock; 65 spinlock_t lock;
66 bool wakeup_needed;
67 unsigned pending_acks; 66 unsigned pending_acks;
68 struct kvm *kvm; 67 struct kvm *kvm;
69 struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ 68 struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
index 1ff819dce7d3..7bcc5b6a4403 100644
--- a/arch/x86/kvm/kvm_cache_regs.h
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -29,4 +29,13 @@ static inline void kvm_rip_write(struct kvm_vcpu *vcpu, unsigned long val)
29 kvm_register_write(vcpu, VCPU_REGS_RIP, val); 29 kvm_register_write(vcpu, VCPU_REGS_RIP, val);
30} 30}
31 31
32static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
33{
34 if (!test_bit(VCPU_EXREG_PDPTR,
35 (unsigned long *)&vcpu->arch.regs_avail))
36 kvm_x86_ops->cache_reg(vcpu, VCPU_EXREG_PDPTR);
37
38 return vcpu->arch.pdptrs[index];
39}
40
32#endif 41#endif
diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h
deleted file mode 100644
index ed66e4c078dc..000000000000
--- a/arch/x86/kvm/kvm_svm.h
+++ /dev/null
@@ -1,51 +0,0 @@
1#ifndef __KVM_SVM_H
2#define __KVM_SVM_H
3
4#include <linux/kernel.h>
5#include <linux/types.h>
6#include <linux/list.h>
7#include <linux/kvm_host.h>
8#include <asm/msr.h>
9
10#include <asm/svm.h>
11
12static const u32 host_save_user_msrs[] = {
13#ifdef CONFIG_X86_64
14 MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
15 MSR_FS_BASE,
16#endif
17 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
18};
19
20#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
21
22struct kvm_vcpu;
23
24struct vcpu_svm {
25 struct kvm_vcpu vcpu;
26 struct vmcb *vmcb;
27 unsigned long vmcb_pa;
28 struct svm_cpu_data *svm_data;
29 uint64_t asid_generation;
30
31 u64 next_rip;
32
33 u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
34 u64 host_gs_base;
35 unsigned long host_cr2;
36
37 u32 *msrpm;
38 struct vmcb *hsave;
39 u64 hsave_msr;
40
41 u64 nested_vmcb;
42
43 /* These are the merged vectors */
44 u32 *nested_msrpm;
45
46 /* gpa pointers to the real vectors */
47 u64 nested_vmcb_msrpm;
48};
49
50#endif
51
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h
index 26bd6ba74e1c..55c7524dda54 100644
--- a/arch/x86/kvm/kvm_timer.h
+++ b/arch/x86/kvm/kvm_timer.h
@@ -6,7 +6,7 @@ struct kvm_timer {
6 bool reinject; 6 bool reinject;
7 struct kvm_timer_ops *t_ops; 7 struct kvm_timer_ops *t_ops;
8 struct kvm *kvm; 8 struct kvm *kvm;
9 int vcpu_id; 9 struct kvm_vcpu *vcpu;
10}; 10};
11 11
12struct kvm_timer_ops { 12struct kvm_timer_ops {
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ae99d83f81a3..1ae5ceba7eb2 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -32,8 +32,11 @@
32#include <asm/current.h> 32#include <asm/current.h>
33#include <asm/apicdef.h> 33#include <asm/apicdef.h>
34#include <asm/atomic.h> 34#include <asm/atomic.h>
35#include <asm/apicdef.h>
35#include "kvm_cache_regs.h" 36#include "kvm_cache_regs.h"
36#include "irq.h" 37#include "irq.h"
38#include "trace.h"
39#include "x86.h"
37 40
38#ifndef CONFIG_X86_64 41#ifndef CONFIG_X86_64
39#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) 42#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
@@ -141,6 +144,26 @@ static inline int apic_lvt_nmi_mode(u32 lvt_val)
141 return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI; 144 return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI;
142} 145}
143 146
147void kvm_apic_set_version(struct kvm_vcpu *vcpu)
148{
149 struct kvm_lapic *apic = vcpu->arch.apic;
150 struct kvm_cpuid_entry2 *feat;
151 u32 v = APIC_VERSION;
152
153 if (!irqchip_in_kernel(vcpu->kvm))
154 return;
155
156 feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0);
157 if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))))
158 v |= APIC_LVR_DIRECTED_EOI;
159 apic_set_reg(apic, APIC_LVR, v);
160}
161
162static inline int apic_x2apic_mode(struct kvm_lapic *apic)
163{
164 return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
165}
166
144static unsigned int apic_lvt_mask[APIC_LVT_NUM] = { 167static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
145 LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */ 168 LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */
146 LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ 169 LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */
@@ -165,36 +188,52 @@ static int find_highest_vector(void *bitmap)
165 188
166static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) 189static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic)
167{ 190{
191 apic->irr_pending = true;
168 return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); 192 return apic_test_and_set_vector(vec, apic->regs + APIC_IRR);
169} 193}
170 194
171static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) 195static inline int apic_search_irr(struct kvm_lapic *apic)
172{ 196{
173 apic_clear_vector(vec, apic->regs + APIC_IRR); 197 return find_highest_vector(apic->regs + APIC_IRR);
174} 198}
175 199
176static inline int apic_find_highest_irr(struct kvm_lapic *apic) 200static inline int apic_find_highest_irr(struct kvm_lapic *apic)
177{ 201{
178 int result; 202 int result;
179 203
180 result = find_highest_vector(apic->regs + APIC_IRR); 204 if (!apic->irr_pending)
205 return -1;
206
207 result = apic_search_irr(apic);
181 ASSERT(result == -1 || result >= 16); 208 ASSERT(result == -1 || result >= 16);
182 209
183 return result; 210 return result;
184} 211}
185 212
213static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
214{
215 apic->irr_pending = false;
216 apic_clear_vector(vec, apic->regs + APIC_IRR);
217 if (apic_search_irr(apic) != -1)
218 apic->irr_pending = true;
219}
220
186int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) 221int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
187{ 222{
188 struct kvm_lapic *apic = vcpu->arch.apic; 223 struct kvm_lapic *apic = vcpu->arch.apic;
189 int highest_irr; 224 int highest_irr;
190 225
226 /* This may race with setting of irr in __apic_accept_irq() and
227 * value returned may be wrong, but kvm_vcpu_kick() in __apic_accept_irq
228 * will cause vmexit immediately and the value will be recalculated
229 * on the next vmentry.
230 */
191 if (!apic) 231 if (!apic)
192 return 0; 232 return 0;
193 highest_irr = apic_find_highest_irr(apic); 233 highest_irr = apic_find_highest_irr(apic);
194 234
195 return highest_irr; 235 return highest_irr;
196} 236}
197EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr);
198 237
199static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, 238static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
200 int vector, int level, int trig_mode); 239 int vector, int level, int trig_mode);
@@ -251,7 +290,12 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
251int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) 290int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
252{ 291{
253 int result = 0; 292 int result = 0;
254 u8 logical_id; 293 u32 logical_id;
294
295 if (apic_x2apic_mode(apic)) {
296 logical_id = apic_get_reg(apic, APIC_LDR);
297 return logical_id & mda;
298 }
255 299
256 logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); 300 logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR));
257 301
@@ -331,6 +375,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
331 break; 375 break;
332 376
333 result = !apic_test_and_set_irr(vector, apic); 377 result = !apic_test_and_set_irr(vector, apic);
378 trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode,
379 trig_mode, vector, !result);
334 if (!result) { 380 if (!result) {
335 if (trig_mode) 381 if (trig_mode)
336 apic_debug("level trig mode repeatedly for " 382 apic_debug("level trig mode repeatedly for "
@@ -425,7 +471,11 @@ static void apic_set_eoi(struct kvm_lapic *apic)
425 trigger_mode = IOAPIC_LEVEL_TRIG; 471 trigger_mode = IOAPIC_LEVEL_TRIG;
426 else 472 else
427 trigger_mode = IOAPIC_EDGE_TRIG; 473 trigger_mode = IOAPIC_EDGE_TRIG;
428 kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); 474 if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) {
475 mutex_lock(&apic->vcpu->kvm->irq_lock);
476 kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
477 mutex_unlock(&apic->vcpu->kvm->irq_lock);
478 }
429} 479}
430 480
431static void apic_send_ipi(struct kvm_lapic *apic) 481static void apic_send_ipi(struct kvm_lapic *apic)
@@ -440,7 +490,12 @@ static void apic_send_ipi(struct kvm_lapic *apic)
440 irq.level = icr_low & APIC_INT_ASSERT; 490 irq.level = icr_low & APIC_INT_ASSERT;
441 irq.trig_mode = icr_low & APIC_INT_LEVELTRIG; 491 irq.trig_mode = icr_low & APIC_INT_LEVELTRIG;
442 irq.shorthand = icr_low & APIC_SHORT_MASK; 492 irq.shorthand = icr_low & APIC_SHORT_MASK;
443 irq.dest_id = GET_APIC_DEST_FIELD(icr_high); 493 if (apic_x2apic_mode(apic))
494 irq.dest_id = icr_high;
495 else
496 irq.dest_id = GET_APIC_DEST_FIELD(icr_high);
497
498 trace_kvm_apic_ipi(icr_low, irq.dest_id);
444 499
445 apic_debug("icr_high 0x%x, icr_low 0x%x, " 500 apic_debug("icr_high 0x%x, icr_low 0x%x, "
446 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " 501 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
@@ -449,7 +504,9 @@ static void apic_send_ipi(struct kvm_lapic *apic)
449 irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, 504 irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode,
450 irq.vector); 505 irq.vector);
451 506
507 mutex_lock(&apic->vcpu->kvm->irq_lock);
452 kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); 508 kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq);
509 mutex_unlock(&apic->vcpu->kvm->irq_lock);
453} 510}
454 511
455static u32 apic_get_tmcct(struct kvm_lapic *apic) 512static u32 apic_get_tmcct(struct kvm_lapic *apic)
@@ -495,12 +552,16 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
495{ 552{
496 u32 val = 0; 553 u32 val = 0;
497 554
498 KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler);
499
500 if (offset >= LAPIC_MMIO_LENGTH) 555 if (offset >= LAPIC_MMIO_LENGTH)
501 return 0; 556 return 0;
502 557
503 switch (offset) { 558 switch (offset) {
559 case APIC_ID:
560 if (apic_x2apic_mode(apic))
561 val = kvm_apic_id(apic);
562 else
563 val = kvm_apic_id(apic) << 24;
564 break;
504 case APIC_ARBPRI: 565 case APIC_ARBPRI:
505 printk(KERN_WARNING "Access APIC ARBPRI register " 566 printk(KERN_WARNING "Access APIC ARBPRI register "
506 "which is for P6\n"); 567 "which is for P6\n");
@@ -522,21 +583,35 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
522 return val; 583 return val;
523} 584}
524 585
525static void apic_mmio_read(struct kvm_io_device *this, 586static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
526 gpa_t address, int len, void *data) 587{
588 return container_of(dev, struct kvm_lapic, dev);
589}
590
591static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
592 void *data)
527{ 593{
528 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
529 unsigned int offset = address - apic->base_address;
530 unsigned char alignment = offset & 0xf; 594 unsigned char alignment = offset & 0xf;
531 u32 result; 595 u32 result;
596 /* this bitmask has a bit cleared for each reserver register */
597 static const u64 rmask = 0x43ff01ffffffe70cULL;
532 598
533 if ((alignment + len) > 4) { 599 if ((alignment + len) > 4) {
534 printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d", 600 apic_debug("KVM_APIC_READ: alignment error %x %d\n",
535 (unsigned long)address, len); 601 offset, len);
536 return; 602 return 1;
537 } 603 }
604
605 if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) {
606 apic_debug("KVM_APIC_READ: read reserved register %x\n",
607 offset);
608 return 1;
609 }
610
538 result = __apic_read(apic, offset & ~0xf); 611 result = __apic_read(apic, offset & ~0xf);
539 612
613 trace_kvm_apic_read(offset, result);
614
540 switch (len) { 615 switch (len) {
541 case 1: 616 case 1:
542 case 2: 617 case 2:
@@ -548,6 +623,28 @@ static void apic_mmio_read(struct kvm_io_device *this,
548 "should be 1,2, or 4 instead\n", len); 623 "should be 1,2, or 4 instead\n", len);
549 break; 624 break;
550 } 625 }
626 return 0;
627}
628
629static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
630{
631 return apic_hw_enabled(apic) &&
632 addr >= apic->base_address &&
633 addr < apic->base_address + LAPIC_MMIO_LENGTH;
634}
635
636static int apic_mmio_read(struct kvm_io_device *this,
637 gpa_t address, int len, void *data)
638{
639 struct kvm_lapic *apic = to_lapic(this);
640 u32 offset = address - apic->base_address;
641
642 if (!apic_mmio_in_range(apic, address))
643 return -EOPNOTSUPP;
644
645 apic_reg_read(apic, offset, len, data);
646
647 return 0;
551} 648}
552 649
553static void update_divide_count(struct kvm_lapic *apic) 650static void update_divide_count(struct kvm_lapic *apic)
@@ -573,6 +670,15 @@ static void start_apic_timer(struct kvm_lapic *apic)
573 670
574 if (!apic->lapic_timer.period) 671 if (!apic->lapic_timer.period)
575 return; 672 return;
673 /*
674 * Do not allow the guest to program periodic timers with small
675 * interval, since the hrtimers are not throttled by the host
676 * scheduler.
677 */
678 if (apic_lvtt_period(apic)) {
679 if (apic->lapic_timer.period < NSEC_PER_MSEC/2)
680 apic->lapic_timer.period = NSEC_PER_MSEC/2;
681 }
576 682
577 hrtimer_start(&apic->lapic_timer.timer, 683 hrtimer_start(&apic->lapic_timer.timer,
578 ktime_add_ns(now, apic->lapic_timer.period), 684 ktime_add_ns(now, apic->lapic_timer.period),
@@ -603,40 +709,18 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
603 apic->vcpu->kvm->arch.vapics_in_nmi_mode--; 709 apic->vcpu->kvm->arch.vapics_in_nmi_mode--;
604} 710}
605 711
606static void apic_mmio_write(struct kvm_io_device *this, 712static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
607 gpa_t address, int len, const void *data)
608{ 713{
609 struct kvm_lapic *apic = (struct kvm_lapic *)this->private; 714 int ret = 0;
610 unsigned int offset = address - apic->base_address;
611 unsigned char alignment = offset & 0xf;
612 u32 val;
613
614 /*
615 * APIC register must be aligned on 128-bits boundary.
616 * 32/64/128 bits registers must be accessed thru 32 bits.
617 * Refer SDM 8.4.1
618 */
619 if (len != 4 || alignment) {
620 /* Don't shout loud, $infamous_os would cause only noise. */
621 apic_debug("apic write: bad size=%d %lx\n",
622 len, (long)address);
623 return;
624 }
625
626 val = *(u32 *) data;
627
628 /* too common printing */
629 if (offset != APIC_EOI)
630 apic_debug("%s: offset 0x%x with length 0x%x, and value is "
631 "0x%x\n", __func__, offset, len, val);
632
633 offset &= 0xff0;
634 715
635 KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); 716 trace_kvm_apic_write(reg, val);
636 717
637 switch (offset) { 718 switch (reg) {
638 case APIC_ID: /* Local APIC ID */ 719 case APIC_ID: /* Local APIC ID */
639 apic_set_reg(apic, APIC_ID, val); 720 if (!apic_x2apic_mode(apic))
721 apic_set_reg(apic, APIC_ID, val);
722 else
723 ret = 1;
640 break; 724 break;
641 725
642 case APIC_TASKPRI: 726 case APIC_TASKPRI:
@@ -649,15 +733,24 @@ static void apic_mmio_write(struct kvm_io_device *this,
649 break; 733 break;
650 734
651 case APIC_LDR: 735 case APIC_LDR:
652 apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK); 736 if (!apic_x2apic_mode(apic))
737 apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK);
738 else
739 ret = 1;
653 break; 740 break;
654 741
655 case APIC_DFR: 742 case APIC_DFR:
656 apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); 743 if (!apic_x2apic_mode(apic))
744 apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
745 else
746 ret = 1;
657 break; 747 break;
658 748
659 case APIC_SPIV: 749 case APIC_SPIV: {
660 apic_set_reg(apic, APIC_SPIV, val & 0x3ff); 750 u32 mask = 0x3ff;
751 if (apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI)
752 mask |= APIC_SPIV_DIRECTED_EOI;
753 apic_set_reg(apic, APIC_SPIV, val & mask);
661 if (!(val & APIC_SPIV_APIC_ENABLED)) { 754 if (!(val & APIC_SPIV_APIC_ENABLED)) {
662 int i; 755 int i;
663 u32 lvt_val; 756 u32 lvt_val;
@@ -672,7 +765,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
672 765
673 } 766 }
674 break; 767 break;
675 768 }
676 case APIC_ICR: 769 case APIC_ICR:
677 /* No delay here, so we always clear the pending bit */ 770 /* No delay here, so we always clear the pending bit */
678 apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); 771 apic_set_reg(apic, APIC_ICR, val & ~(1 << 12));
@@ -680,7 +773,9 @@ static void apic_mmio_write(struct kvm_io_device *this,
680 break; 773 break;
681 774
682 case APIC_ICR2: 775 case APIC_ICR2:
683 apic_set_reg(apic, APIC_ICR2, val & 0xff000000); 776 if (!apic_x2apic_mode(apic))
777 val &= 0xff000000;
778 apic_set_reg(apic, APIC_ICR2, val);
684 break; 779 break;
685 780
686 case APIC_LVT0: 781 case APIC_LVT0:
@@ -694,8 +789,8 @@ static void apic_mmio_write(struct kvm_io_device *this,
694 if (!apic_sw_enabled(apic)) 789 if (!apic_sw_enabled(apic))
695 val |= APIC_LVT_MASKED; 790 val |= APIC_LVT_MASKED;
696 791
697 val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4]; 792 val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
698 apic_set_reg(apic, offset, val); 793 apic_set_reg(apic, reg, val);
699 794
700 break; 795 break;
701 796
@@ -703,7 +798,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
703 hrtimer_cancel(&apic->lapic_timer.timer); 798 hrtimer_cancel(&apic->lapic_timer.timer);
704 apic_set_reg(apic, APIC_TMICT, val); 799 apic_set_reg(apic, APIC_TMICT, val);
705 start_apic_timer(apic); 800 start_apic_timer(apic);
706 return; 801 break;
707 802
708 case APIC_TDCR: 803 case APIC_TDCR:
709 if (val & 4) 804 if (val & 4)
@@ -712,27 +807,59 @@ static void apic_mmio_write(struct kvm_io_device *this,
712 update_divide_count(apic); 807 update_divide_count(apic);
713 break; 808 break;
714 809
810 case APIC_ESR:
811 if (apic_x2apic_mode(apic) && val != 0) {
812 printk(KERN_ERR "KVM_WRITE:ESR not zero %x\n", val);
813 ret = 1;
814 }
815 break;
816
817 case APIC_SELF_IPI:
818 if (apic_x2apic_mode(apic)) {
819 apic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff));
820 } else
821 ret = 1;
822 break;
715 default: 823 default:
716 apic_debug("Local APIC Write to read-only register %x\n", 824 ret = 1;
717 offset);
718 break; 825 break;
719 } 826 }
720 827 if (ret)
828 apic_debug("Local APIC Write to read-only register %x\n", reg);
829 return ret;
721} 830}
722 831
723static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr, 832static int apic_mmio_write(struct kvm_io_device *this,
724 int len, int size) 833 gpa_t address, int len, const void *data)
725{ 834{
726 struct kvm_lapic *apic = (struct kvm_lapic *)this->private; 835 struct kvm_lapic *apic = to_lapic(this);
727 int ret = 0; 836 unsigned int offset = address - apic->base_address;
837 u32 val;
728 838
839 if (!apic_mmio_in_range(apic, address))
840 return -EOPNOTSUPP;
729 841
730 if (apic_hw_enabled(apic) && 842 /*
731 (addr >= apic->base_address) && 843 * APIC register must be aligned on 128-bits boundary.
732 (addr < (apic->base_address + LAPIC_MMIO_LENGTH))) 844 * 32/64/128 bits registers must be accessed thru 32 bits.
733 ret = 1; 845 * Refer SDM 8.4.1
846 */
847 if (len != 4 || (offset & 0xf)) {
848 /* Don't shout loud, $infamous_os would cause only noise. */
849 apic_debug("apic write: bad size=%d %lx\n", len, (long)address);
850 return 0;
851 }
734 852
735 return ret; 853 val = *(u32*)data;
854
855 /* too common printing */
856 if (offset != APIC_EOI)
857 apic_debug("%s: offset 0x%x with length 0x%x, and value is "
858 "0x%x\n", __func__, offset, len, val);
859
860 apic_reg_write(apic, offset & 0xff0, val);
861
862 return 0;
736} 863}
737 864
738void kvm_free_lapic(struct kvm_vcpu *vcpu) 865void kvm_free_lapic(struct kvm_vcpu *vcpu)
@@ -763,7 +890,6 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
763 apic_set_tpr(apic, ((cr8 & 0x0f) << 4) 890 apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
764 | (apic_get_reg(apic, APIC_TASKPRI) & 4)); 891 | (apic_get_reg(apic, APIC_TASKPRI) & 4));
765} 892}
766EXPORT_SYMBOL_GPL(kvm_lapic_set_tpr);
767 893
768u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) 894u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
769{ 895{
@@ -776,7 +902,6 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
776 902
777 return (tpr & 0xf0) >> 4; 903 return (tpr & 0xf0) >> 4;
778} 904}
779EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8);
780 905
781void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) 906void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
782{ 907{
@@ -787,10 +912,16 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
787 vcpu->arch.apic_base = value; 912 vcpu->arch.apic_base = value;
788 return; 913 return;
789 } 914 }
790 if (apic->vcpu->vcpu_id) 915
916 if (!kvm_vcpu_is_bsp(apic->vcpu))
791 value &= ~MSR_IA32_APICBASE_BSP; 917 value &= ~MSR_IA32_APICBASE_BSP;
792 918
793 vcpu->arch.apic_base = value; 919 vcpu->arch.apic_base = value;
920 if (apic_x2apic_mode(apic)) {
921 u32 id = kvm_apic_id(apic);
922 u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf));
923 apic_set_reg(apic, APIC_LDR, ldr);
924 }
794 apic->base_address = apic->vcpu->arch.apic_base & 925 apic->base_address = apic->vcpu->arch.apic_base &
795 MSR_IA32_APICBASE_BASE; 926 MSR_IA32_APICBASE_BASE;
796 927
@@ -800,12 +931,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
800 931
801} 932}
802 933
803u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu)
804{
805 return vcpu->arch.apic_base;
806}
807EXPORT_SYMBOL_GPL(kvm_lapic_get_base);
808
809void kvm_lapic_reset(struct kvm_vcpu *vcpu) 934void kvm_lapic_reset(struct kvm_vcpu *vcpu)
810{ 935{
811 struct kvm_lapic *apic; 936 struct kvm_lapic *apic;
@@ -821,7 +946,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
821 hrtimer_cancel(&apic->lapic_timer.timer); 946 hrtimer_cancel(&apic->lapic_timer.timer);
822 947
823 apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24); 948 apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24);
824 apic_set_reg(apic, APIC_LVR, APIC_VERSION); 949 kvm_apic_set_version(apic->vcpu);
825 950
826 for (i = 0; i < APIC_LVT_NUM; i++) 951 for (i = 0; i < APIC_LVT_NUM; i++)
827 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); 952 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
@@ -842,9 +967,10 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
842 apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); 967 apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
843 apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); 968 apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
844 } 969 }
970 apic->irr_pending = false;
845 update_divide_count(apic); 971 update_divide_count(apic);
846 atomic_set(&apic->lapic_timer.pending, 0); 972 atomic_set(&apic->lapic_timer.pending, 0);
847 if (vcpu->vcpu_id == 0) 973 if (kvm_vcpu_is_bsp(vcpu))
848 vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; 974 vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP;
849 apic_update_ppr(apic); 975 apic_update_ppr(apic);
850 976
@@ -855,7 +981,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
855 vcpu, kvm_apic_id(apic), 981 vcpu, kvm_apic_id(apic),
856 vcpu->arch.apic_base, apic->base_address); 982 vcpu->arch.apic_base, apic->base_address);
857} 983}
858EXPORT_SYMBOL_GPL(kvm_lapic_reset);
859 984
860bool kvm_apic_present(struct kvm_vcpu *vcpu) 985bool kvm_apic_present(struct kvm_vcpu *vcpu)
861{ 986{
@@ -866,7 +991,6 @@ int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
866{ 991{
867 return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); 992 return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic);
868} 993}
869EXPORT_SYMBOL_GPL(kvm_lapic_enabled);
870 994
871/* 995/*
872 *---------------------------------------------------------------------- 996 *----------------------------------------------------------------------
@@ -917,6 +1041,11 @@ static struct kvm_timer_ops lapic_timer_ops = {
917 .is_periodic = lapic_is_periodic, 1041 .is_periodic = lapic_is_periodic,
918}; 1042};
919 1043
1044static const struct kvm_io_device_ops apic_mmio_ops = {
1045 .read = apic_mmio_read,
1046 .write = apic_mmio_write,
1047};
1048
920int kvm_create_lapic(struct kvm_vcpu *vcpu) 1049int kvm_create_lapic(struct kvm_vcpu *vcpu)
921{ 1050{
922 struct kvm_lapic *apic; 1051 struct kvm_lapic *apic;
@@ -945,16 +1074,13 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
945 apic->lapic_timer.timer.function = kvm_timer_fn; 1074 apic->lapic_timer.timer.function = kvm_timer_fn;
946 apic->lapic_timer.t_ops = &lapic_timer_ops; 1075 apic->lapic_timer.t_ops = &lapic_timer_ops;
947 apic->lapic_timer.kvm = vcpu->kvm; 1076 apic->lapic_timer.kvm = vcpu->kvm;
948 apic->lapic_timer.vcpu_id = vcpu->vcpu_id; 1077 apic->lapic_timer.vcpu = vcpu;
949 1078
950 apic->base_address = APIC_DEFAULT_PHYS_BASE; 1079 apic->base_address = APIC_DEFAULT_PHYS_BASE;
951 vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE; 1080 vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE;
952 1081
953 kvm_lapic_reset(vcpu); 1082 kvm_lapic_reset(vcpu);
954 apic->dev.read = apic_mmio_read; 1083 kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
955 apic->dev.write = apic_mmio_write;
956 apic->dev.in_range = apic_mmio_range;
957 apic->dev.private = apic;
958 1084
959 return 0; 1085 return 0;
960nomem_free_apic: 1086nomem_free_apic:
@@ -962,7 +1088,6 @@ nomem_free_apic:
962nomem: 1088nomem:
963 return -ENOMEM; 1089 return -ENOMEM;
964} 1090}
965EXPORT_SYMBOL_GPL(kvm_create_lapic);
966 1091
967int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) 1092int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
968{ 1093{
@@ -985,7 +1110,7 @@ int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu)
985 u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); 1110 u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0);
986 int r = 0; 1111 int r = 0;
987 1112
988 if (vcpu->vcpu_id == 0) { 1113 if (kvm_vcpu_is_bsp(vcpu)) {
989 if (!apic_hw_enabled(vcpu->arch.apic)) 1114 if (!apic_hw_enabled(vcpu->arch.apic))
990 r = 1; 1115 r = 1;
991 if ((lvt0 & APIC_LVT_MASKED) == 0 && 1116 if ((lvt0 & APIC_LVT_MASKED) == 0 &&
@@ -1025,7 +1150,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
1025 1150
1026 apic->base_address = vcpu->arch.apic_base & 1151 apic->base_address = vcpu->arch.apic_base &
1027 MSR_IA32_APICBASE_BASE; 1152 MSR_IA32_APICBASE_BASE;
1028 apic_set_reg(apic, APIC_LVR, APIC_VERSION); 1153 kvm_apic_set_version(vcpu);
1154
1029 apic_update_ppr(apic); 1155 apic_update_ppr(apic);
1030 hrtimer_cancel(&apic->lapic_timer.timer); 1156 hrtimer_cancel(&apic->lapic_timer.timer);
1031 update_divide_count(apic); 1157 update_divide_count(apic);
@@ -1092,3 +1218,35 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
1092 1218
1093 vcpu->arch.apic->vapic_addr = vapic_addr; 1219 vcpu->arch.apic->vapic_addr = vapic_addr;
1094} 1220}
1221
1222int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1223{
1224 struct kvm_lapic *apic = vcpu->arch.apic;
1225 u32 reg = (msr - APIC_BASE_MSR) << 4;
1226
1227 if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
1228 return 1;
1229
1230 /* if this is ICR write vector before command */
1231 if (msr == 0x830)
1232 apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
1233 return apic_reg_write(apic, reg, (u32)data);
1234}
1235
1236int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
1237{
1238 struct kvm_lapic *apic = vcpu->arch.apic;
1239 u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0;
1240
1241 if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
1242 return 1;
1243
1244 if (apic_reg_read(apic, reg, 4, &low))
1245 return 1;
1246 if (msr == 0x830)
1247 apic_reg_read(apic, APIC_ICR2, 4, &high);
1248
1249 *data = (((u64)high) << 32) | low;
1250
1251 return 0;
1252}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index a587f8349c46..40010b09c4aa 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -12,6 +12,7 @@ struct kvm_lapic {
12 struct kvm_timer lapic_timer; 12 struct kvm_timer lapic_timer;
13 u32 divide_count; 13 u32 divide_count;
14 struct kvm_vcpu *vcpu; 14 struct kvm_vcpu *vcpu;
15 bool irr_pending;
15 struct page *regs_page; 16 struct page *regs_page;
16 void *regs; 17 void *regs;
17 gpa_t vapic_addr; 18 gpa_t vapic_addr;
@@ -28,6 +29,7 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
28void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); 29void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
29void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); 30void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
30u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); 31u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
32void kvm_apic_set_version(struct kvm_vcpu *vcpu);
31 33
32int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); 34int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
33int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); 35int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
@@ -44,4 +46,6 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
44void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); 46void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
45void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); 47void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
46 48
49int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
50int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
47#endif 51#endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 0ef5bb2b4043..eca41ae9f453 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include "mmu.h" 20#include "mmu.h"
21#include "kvm_cache_regs.h"
21 22
22#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
23#include <linux/types.h> 24#include <linux/types.h>
@@ -107,6 +108,9 @@ module_param(oos_shadow, bool, 0644);
107 108
108#define PT32_LEVEL_MASK(level) \ 109#define PT32_LEVEL_MASK(level) \
109 (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level)) 110 (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level))
111#define PT32_LVL_OFFSET_MASK(level) \
112 (PT32_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \
113 * PT32_LEVEL_BITS))) - 1))
110 114
111#define PT32_INDEX(address, level)\ 115#define PT32_INDEX(address, level)\
112 (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) 116 (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1))
@@ -115,10 +119,19 @@ module_param(oos_shadow, bool, 0644);
115#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) 119#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1))
116#define PT64_DIR_BASE_ADDR_MASK \ 120#define PT64_DIR_BASE_ADDR_MASK \
117 (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1)) 121 (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1))
122#define PT64_LVL_ADDR_MASK(level) \
123 (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \
124 * PT64_LEVEL_BITS))) - 1))
125#define PT64_LVL_OFFSET_MASK(level) \
126 (PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \
127 * PT64_LEVEL_BITS))) - 1))
118 128
119#define PT32_BASE_ADDR_MASK PAGE_MASK 129#define PT32_BASE_ADDR_MASK PAGE_MASK
120#define PT32_DIR_BASE_ADDR_MASK \ 130#define PT32_DIR_BASE_ADDR_MASK \
121 (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1)) 131 (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1))
132#define PT32_LVL_ADDR_MASK(level) \
133 (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \
134 * PT32_LEVEL_BITS))) - 1))
122 135
123#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ 136#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \
124 | PT64_NX_MASK) 137 | PT64_NX_MASK)
@@ -129,6 +142,7 @@ module_param(oos_shadow, bool, 0644);
129#define PFERR_RSVD_MASK (1U << 3) 142#define PFERR_RSVD_MASK (1U << 3)
130#define PFERR_FETCH_MASK (1U << 4) 143#define PFERR_FETCH_MASK (1U << 4)
131 144
145#define PT_PDPE_LEVEL 3
132#define PT_DIRECTORY_LEVEL 2 146#define PT_DIRECTORY_LEVEL 2
133#define PT_PAGE_TABLE_LEVEL 1 147#define PT_PAGE_TABLE_LEVEL 1
134 148
@@ -139,10 +153,13 @@ module_param(oos_shadow, bool, 0644);
139#define ACC_USER_MASK PT_USER_MASK 153#define ACC_USER_MASK PT_USER_MASK
140#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) 154#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
141 155
156#define CREATE_TRACE_POINTS
157#include "mmutrace.h"
158
142#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) 159#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
143 160
144struct kvm_rmap_desc { 161struct kvm_rmap_desc {
145 u64 *shadow_ptes[RMAP_EXT]; 162 u64 *sptes[RMAP_EXT];
146 struct kvm_rmap_desc *more; 163 struct kvm_rmap_desc *more;
147}; 164};
148 165
@@ -239,16 +256,25 @@ static int is_writeble_pte(unsigned long pte)
239 return pte & PT_WRITABLE_MASK; 256 return pte & PT_WRITABLE_MASK;
240} 257}
241 258
242static int is_dirty_pte(unsigned long pte) 259static int is_dirty_gpte(unsigned long pte)
243{ 260{
244 return pte & shadow_dirty_mask; 261 return pte & PT_DIRTY_MASK;
245} 262}
246 263
247static int is_rmap_pte(u64 pte) 264static int is_rmap_spte(u64 pte)
248{ 265{
249 return is_shadow_present_pte(pte); 266 return is_shadow_present_pte(pte);
250} 267}
251 268
269static int is_last_spte(u64 pte, int level)
270{
271 if (level == PT_PAGE_TABLE_LEVEL)
272 return 1;
273 if (is_large_pte(pte))
274 return 1;
275 return 0;
276}
277
252static pfn_t spte_to_pfn(u64 pte) 278static pfn_t spte_to_pfn(u64 pte)
253{ 279{
254 return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; 280 return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
@@ -261,7 +287,7 @@ static gfn_t pse36_gfn_delta(u32 gpte)
261 return (gpte & PT32_DIR_PSE36_MASK) << shift; 287 return (gpte & PT32_DIR_PSE36_MASK) << shift;
262} 288}
263 289
264static void set_shadow_pte(u64 *sptep, u64 spte) 290static void __set_spte(u64 *sptep, u64 spte)
265{ 291{
266#ifdef CONFIG_X86_64 292#ifdef CONFIG_X86_64
267 set_64bit((unsigned long *)sptep, spte); 293 set_64bit((unsigned long *)sptep, spte);
@@ -380,37 +406,52 @@ static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd)
380 * Return the pointer to the largepage write count for a given 406 * Return the pointer to the largepage write count for a given
381 * gfn, handling slots that are not large page aligned. 407 * gfn, handling slots that are not large page aligned.
382 */ 408 */
383static int *slot_largepage_idx(gfn_t gfn, struct kvm_memory_slot *slot) 409static int *slot_largepage_idx(gfn_t gfn,
410 struct kvm_memory_slot *slot,
411 int level)
384{ 412{
385 unsigned long idx; 413 unsigned long idx;
386 414
387 idx = (gfn / KVM_PAGES_PER_HPAGE) - 415 idx = (gfn / KVM_PAGES_PER_HPAGE(level)) -
388 (slot->base_gfn / KVM_PAGES_PER_HPAGE); 416 (slot->base_gfn / KVM_PAGES_PER_HPAGE(level));
389 return &slot->lpage_info[idx].write_count; 417 return &slot->lpage_info[level - 2][idx].write_count;
390} 418}
391 419
392static void account_shadowed(struct kvm *kvm, gfn_t gfn) 420static void account_shadowed(struct kvm *kvm, gfn_t gfn)
393{ 421{
422 struct kvm_memory_slot *slot;
394 int *write_count; 423 int *write_count;
424 int i;
395 425
396 gfn = unalias_gfn(kvm, gfn); 426 gfn = unalias_gfn(kvm, gfn);
397 write_count = slot_largepage_idx(gfn, 427
398 gfn_to_memslot_unaliased(kvm, gfn)); 428 slot = gfn_to_memslot_unaliased(kvm, gfn);
399 *write_count += 1; 429 for (i = PT_DIRECTORY_LEVEL;
430 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
431 write_count = slot_largepage_idx(gfn, slot, i);
432 *write_count += 1;
433 }
400} 434}
401 435
402static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) 436static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn)
403{ 437{
438 struct kvm_memory_slot *slot;
404 int *write_count; 439 int *write_count;
440 int i;
405 441
406 gfn = unalias_gfn(kvm, gfn); 442 gfn = unalias_gfn(kvm, gfn);
407 write_count = slot_largepage_idx(gfn, 443 for (i = PT_DIRECTORY_LEVEL;
408 gfn_to_memslot_unaliased(kvm, gfn)); 444 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
409 *write_count -= 1; 445 slot = gfn_to_memslot_unaliased(kvm, gfn);
410 WARN_ON(*write_count < 0); 446 write_count = slot_largepage_idx(gfn, slot, i);
447 *write_count -= 1;
448 WARN_ON(*write_count < 0);
449 }
411} 450}
412 451
413static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn) 452static int has_wrprotected_page(struct kvm *kvm,
453 gfn_t gfn,
454 int level)
414{ 455{
415 struct kvm_memory_slot *slot; 456 struct kvm_memory_slot *slot;
416 int *largepage_idx; 457 int *largepage_idx;
@@ -418,47 +459,67 @@ static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn)
418 gfn = unalias_gfn(kvm, gfn); 459 gfn = unalias_gfn(kvm, gfn);
419 slot = gfn_to_memslot_unaliased(kvm, gfn); 460 slot = gfn_to_memslot_unaliased(kvm, gfn);
420 if (slot) { 461 if (slot) {
421 largepage_idx = slot_largepage_idx(gfn, slot); 462 largepage_idx = slot_largepage_idx(gfn, slot, level);
422 return *largepage_idx; 463 return *largepage_idx;
423 } 464 }
424 465
425 return 1; 466 return 1;
426} 467}
427 468
428static int host_largepage_backed(struct kvm *kvm, gfn_t gfn) 469static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
429{ 470{
471 unsigned long page_size = PAGE_SIZE;
430 struct vm_area_struct *vma; 472 struct vm_area_struct *vma;
431 unsigned long addr; 473 unsigned long addr;
432 int ret = 0; 474 int i, ret = 0;
433 475
434 addr = gfn_to_hva(kvm, gfn); 476 addr = gfn_to_hva(kvm, gfn);
435 if (kvm_is_error_hva(addr)) 477 if (kvm_is_error_hva(addr))
436 return ret; 478 return page_size;
437 479
438 down_read(&current->mm->mmap_sem); 480 down_read(&current->mm->mmap_sem);
439 vma = find_vma(current->mm, addr); 481 vma = find_vma(current->mm, addr);
440 if (vma && is_vm_hugetlb_page(vma)) 482 if (!vma)
441 ret = 1; 483 goto out;
484
485 page_size = vma_kernel_pagesize(vma);
486
487out:
442 up_read(&current->mm->mmap_sem); 488 up_read(&current->mm->mmap_sem);
443 489
490 for (i = PT_PAGE_TABLE_LEVEL;
491 i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) {
492 if (page_size >= KVM_HPAGE_SIZE(i))
493 ret = i;
494 else
495 break;
496 }
497
444 return ret; 498 return ret;
445} 499}
446 500
447static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn) 501static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
448{ 502{
449 struct kvm_memory_slot *slot; 503 struct kvm_memory_slot *slot;
450 504 int host_level;
451 if (has_wrprotected_page(vcpu->kvm, large_gfn)) 505 int level = PT_PAGE_TABLE_LEVEL;
452 return 0;
453
454 if (!host_largepage_backed(vcpu->kvm, large_gfn))
455 return 0;
456 506
457 slot = gfn_to_memslot(vcpu->kvm, large_gfn); 507 slot = gfn_to_memslot(vcpu->kvm, large_gfn);
458 if (slot && slot->dirty_bitmap) 508 if (slot && slot->dirty_bitmap)
459 return 0; 509 return PT_PAGE_TABLE_LEVEL;
460 510
461 return 1; 511 host_level = host_mapping_level(vcpu->kvm, large_gfn);
512
513 if (host_level == PT_PAGE_TABLE_LEVEL)
514 return host_level;
515
516 for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) {
517
518 if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
519 break;
520 }
521
522 return level - 1;
462} 523}
463 524
464/* 525/*
@@ -466,19 +527,19 @@ static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn)
466 * Note: gfn must be unaliased before this function get called 527 * Note: gfn must be unaliased before this function get called
467 */ 528 */
468 529
469static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage) 530static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level)
470{ 531{
471 struct kvm_memory_slot *slot; 532 struct kvm_memory_slot *slot;
472 unsigned long idx; 533 unsigned long idx;
473 534
474 slot = gfn_to_memslot(kvm, gfn); 535 slot = gfn_to_memslot(kvm, gfn);
475 if (!lpage) 536 if (likely(level == PT_PAGE_TABLE_LEVEL))
476 return &slot->rmap[gfn - slot->base_gfn]; 537 return &slot->rmap[gfn - slot->base_gfn];
477 538
478 idx = (gfn / KVM_PAGES_PER_HPAGE) - 539 idx = (gfn / KVM_PAGES_PER_HPAGE(level)) -
479 (slot->base_gfn / KVM_PAGES_PER_HPAGE); 540 (slot->base_gfn / KVM_PAGES_PER_HPAGE(level));
480 541
481 return &slot->lpage_info[idx].rmap_pde; 542 return &slot->lpage_info[level - 2][idx].rmap_pde;
482} 543}
483 544
484/* 545/*
@@ -494,42 +555,42 @@ static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage)
494 * the spte was not added. 555 * the spte was not added.
495 * 556 *
496 */ 557 */
497static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) 558static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
498{ 559{
499 struct kvm_mmu_page *sp; 560 struct kvm_mmu_page *sp;
500 struct kvm_rmap_desc *desc; 561 struct kvm_rmap_desc *desc;
501 unsigned long *rmapp; 562 unsigned long *rmapp;
502 int i, count = 0; 563 int i, count = 0;
503 564
504 if (!is_rmap_pte(*spte)) 565 if (!is_rmap_spte(*spte))
505 return count; 566 return count;
506 gfn = unalias_gfn(vcpu->kvm, gfn); 567 gfn = unalias_gfn(vcpu->kvm, gfn);
507 sp = page_header(__pa(spte)); 568 sp = page_header(__pa(spte));
508 sp->gfns[spte - sp->spt] = gfn; 569 sp->gfns[spte - sp->spt] = gfn;
509 rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage); 570 rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
510 if (!*rmapp) { 571 if (!*rmapp) {
511 rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte); 572 rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte);
512 *rmapp = (unsigned long)spte; 573 *rmapp = (unsigned long)spte;
513 } else if (!(*rmapp & 1)) { 574 } else if (!(*rmapp & 1)) {
514 rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte); 575 rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte);
515 desc = mmu_alloc_rmap_desc(vcpu); 576 desc = mmu_alloc_rmap_desc(vcpu);
516 desc->shadow_ptes[0] = (u64 *)*rmapp; 577 desc->sptes[0] = (u64 *)*rmapp;
517 desc->shadow_ptes[1] = spte; 578 desc->sptes[1] = spte;
518 *rmapp = (unsigned long)desc | 1; 579 *rmapp = (unsigned long)desc | 1;
519 } else { 580 } else {
520 rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte); 581 rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte);
521 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); 582 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
522 while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) { 583 while (desc->sptes[RMAP_EXT-1] && desc->more) {
523 desc = desc->more; 584 desc = desc->more;
524 count += RMAP_EXT; 585 count += RMAP_EXT;
525 } 586 }
526 if (desc->shadow_ptes[RMAP_EXT-1]) { 587 if (desc->sptes[RMAP_EXT-1]) {
527 desc->more = mmu_alloc_rmap_desc(vcpu); 588 desc->more = mmu_alloc_rmap_desc(vcpu);
528 desc = desc->more; 589 desc = desc->more;
529 } 590 }
530 for (i = 0; desc->shadow_ptes[i]; ++i) 591 for (i = 0; desc->sptes[i]; ++i)
531 ; 592 ;
532 desc->shadow_ptes[i] = spte; 593 desc->sptes[i] = spte;
533 } 594 }
534 return count; 595 return count;
535} 596}
@@ -541,14 +602,14 @@ static void rmap_desc_remove_entry(unsigned long *rmapp,
541{ 602{
542 int j; 603 int j;
543 604
544 for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j) 605 for (j = RMAP_EXT - 1; !desc->sptes[j] && j > i; --j)
545 ; 606 ;
546 desc->shadow_ptes[i] = desc->shadow_ptes[j]; 607 desc->sptes[i] = desc->sptes[j];
547 desc->shadow_ptes[j] = NULL; 608 desc->sptes[j] = NULL;
548 if (j != 0) 609 if (j != 0)
549 return; 610 return;
550 if (!prev_desc && !desc->more) 611 if (!prev_desc && !desc->more)
551 *rmapp = (unsigned long)desc->shadow_ptes[0]; 612 *rmapp = (unsigned long)desc->sptes[0];
552 else 613 else
553 if (prev_desc) 614 if (prev_desc)
554 prev_desc->more = desc->more; 615 prev_desc->more = desc->more;
@@ -566,7 +627,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
566 unsigned long *rmapp; 627 unsigned long *rmapp;
567 int i; 628 int i;
568 629
569 if (!is_rmap_pte(*spte)) 630 if (!is_rmap_spte(*spte))
570 return; 631 return;
571 sp = page_header(__pa(spte)); 632 sp = page_header(__pa(spte));
572 pfn = spte_to_pfn(*spte); 633 pfn = spte_to_pfn(*spte);
@@ -576,7 +637,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
576 kvm_release_pfn_dirty(pfn); 637 kvm_release_pfn_dirty(pfn);
577 else 638 else
578 kvm_release_pfn_clean(pfn); 639 kvm_release_pfn_clean(pfn);
579 rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], is_large_pte(*spte)); 640 rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level);
580 if (!*rmapp) { 641 if (!*rmapp) {
581 printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte); 642 printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
582 BUG(); 643 BUG();
@@ -593,8 +654,8 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
593 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); 654 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
594 prev_desc = NULL; 655 prev_desc = NULL;
595 while (desc) { 656 while (desc) {
596 for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) 657 for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i)
597 if (desc->shadow_ptes[i] == spte) { 658 if (desc->sptes[i] == spte) {
598 rmap_desc_remove_entry(rmapp, 659 rmap_desc_remove_entry(rmapp,
599 desc, i, 660 desc, i,
600 prev_desc); 661 prev_desc);
@@ -625,10 +686,10 @@ static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte)
625 prev_desc = NULL; 686 prev_desc = NULL;
626 prev_spte = NULL; 687 prev_spte = NULL;
627 while (desc) { 688 while (desc) {
628 for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) { 689 for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i) {
629 if (prev_spte == spte) 690 if (prev_spte == spte)
630 return desc->shadow_ptes[i]; 691 return desc->sptes[i];
631 prev_spte = desc->shadow_ptes[i]; 692 prev_spte = desc->sptes[i];
632 } 693 }
633 desc = desc->more; 694 desc = desc->more;
634 } 695 }
@@ -639,10 +700,10 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
639{ 700{
640 unsigned long *rmapp; 701 unsigned long *rmapp;
641 u64 *spte; 702 u64 *spte;
642 int write_protected = 0; 703 int i, write_protected = 0;
643 704
644 gfn = unalias_gfn(kvm, gfn); 705 gfn = unalias_gfn(kvm, gfn);
645 rmapp = gfn_to_rmap(kvm, gfn, 0); 706 rmapp = gfn_to_rmap(kvm, gfn, PT_PAGE_TABLE_LEVEL);
646 707
647 spte = rmap_next(kvm, rmapp, NULL); 708 spte = rmap_next(kvm, rmapp, NULL);
648 while (spte) { 709 while (spte) {
@@ -650,7 +711,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
650 BUG_ON(!(*spte & PT_PRESENT_MASK)); 711 BUG_ON(!(*spte & PT_PRESENT_MASK));
651 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); 712 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
652 if (is_writeble_pte(*spte)) { 713 if (is_writeble_pte(*spte)) {
653 set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK); 714 __set_spte(spte, *spte & ~PT_WRITABLE_MASK);
654 write_protected = 1; 715 write_protected = 1;
655 } 716 }
656 spte = rmap_next(kvm, rmapp, spte); 717 spte = rmap_next(kvm, rmapp, spte);
@@ -664,21 +725,24 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
664 } 725 }
665 726
666 /* check for huge page mappings */ 727 /* check for huge page mappings */
667 rmapp = gfn_to_rmap(kvm, gfn, 1); 728 for (i = PT_DIRECTORY_LEVEL;
668 spte = rmap_next(kvm, rmapp, NULL); 729 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
669 while (spte) { 730 rmapp = gfn_to_rmap(kvm, gfn, i);
670 BUG_ON(!spte); 731 spte = rmap_next(kvm, rmapp, NULL);
671 BUG_ON(!(*spte & PT_PRESENT_MASK)); 732 while (spte) {
672 BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)); 733 BUG_ON(!spte);
673 pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn); 734 BUG_ON(!(*spte & PT_PRESENT_MASK));
674 if (is_writeble_pte(*spte)) { 735 BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK));
675 rmap_remove(kvm, spte); 736 pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
676 --kvm->stat.lpages; 737 if (is_writeble_pte(*spte)) {
677 set_shadow_pte(spte, shadow_trap_nonpresent_pte); 738 rmap_remove(kvm, spte);
678 spte = NULL; 739 --kvm->stat.lpages;
679 write_protected = 1; 740 __set_spte(spte, shadow_trap_nonpresent_pte);
741 spte = NULL;
742 write_protected = 1;
743 }
744 spte = rmap_next(kvm, rmapp, spte);
680 } 745 }
681 spte = rmap_next(kvm, rmapp, spte);
682 } 746 }
683 747
684 return write_protected; 748 return write_protected;
@@ -693,7 +757,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
693 BUG_ON(!(*spte & PT_PRESENT_MASK)); 757 BUG_ON(!(*spte & PT_PRESENT_MASK));
694 rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", spte, *spte); 758 rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", spte, *spte);
695 rmap_remove(kvm, spte); 759 rmap_remove(kvm, spte);
696 set_shadow_pte(spte, shadow_trap_nonpresent_pte); 760 __set_spte(spte, shadow_trap_nonpresent_pte);
697 need_tlb_flush = 1; 761 need_tlb_flush = 1;
698 } 762 }
699 return need_tlb_flush; 763 return need_tlb_flush;
@@ -702,7 +766,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
702static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, 766static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
703 int (*handler)(struct kvm *kvm, unsigned long *rmapp)) 767 int (*handler)(struct kvm *kvm, unsigned long *rmapp))
704{ 768{
705 int i; 769 int i, j;
706 int retval = 0; 770 int retval = 0;
707 771
708 /* 772 /*
@@ -721,11 +785,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
721 end = start + (memslot->npages << PAGE_SHIFT); 785 end = start + (memslot->npages << PAGE_SHIFT);
722 if (hva >= start && hva < end) { 786 if (hva >= start && hva < end) {
723 gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; 787 gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
788
724 retval |= handler(kvm, &memslot->rmap[gfn_offset]); 789 retval |= handler(kvm, &memslot->rmap[gfn_offset]);
725 retval |= handler(kvm, 790
726 &memslot->lpage_info[ 791 for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
727 gfn_offset / 792 int idx = gfn_offset;
728 KVM_PAGES_PER_HPAGE].rmap_pde); 793 idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j);
794 retval |= handler(kvm,
795 &memslot->lpage_info[j][idx].rmap_pde);
796 }
729 } 797 }
730 } 798 }
731 799
@@ -763,12 +831,15 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp)
763 831
764#define RMAP_RECYCLE_THRESHOLD 1000 832#define RMAP_RECYCLE_THRESHOLD 1000
765 833
766static void rmap_recycle(struct kvm_vcpu *vcpu, gfn_t gfn, int lpage) 834static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
767{ 835{
768 unsigned long *rmapp; 836 unsigned long *rmapp;
837 struct kvm_mmu_page *sp;
838
839 sp = page_header(__pa(spte));
769 840
770 gfn = unalias_gfn(vcpu->kvm, gfn); 841 gfn = unalias_gfn(vcpu->kvm, gfn);
771 rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage); 842 rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
772 843
773 kvm_unmap_rmapp(vcpu->kvm, rmapp); 844 kvm_unmap_rmapp(vcpu->kvm, rmapp);
774 kvm_flush_remote_tlbs(vcpu->kvm); 845 kvm_flush_remote_tlbs(vcpu->kvm);
@@ -1109,6 +1180,7 @@ static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
1109 return 1; 1180 return 1;
1110 } 1181 }
1111 1182
1183 trace_kvm_mmu_sync_page(sp);
1112 if (rmap_write_protect(vcpu->kvm, sp->gfn)) 1184 if (rmap_write_protect(vcpu->kvm, sp->gfn))
1113 kvm_flush_remote_tlbs(vcpu->kvm); 1185 kvm_flush_remote_tlbs(vcpu->kvm);
1114 kvm_unlink_unsync_page(vcpu->kvm, sp); 1186 kvm_unlink_unsync_page(vcpu->kvm, sp);
@@ -1231,8 +1303,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1231 quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; 1303 quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1;
1232 role.quadrant = quadrant; 1304 role.quadrant = quadrant;
1233 } 1305 }
1234 pgprintk("%s: looking gfn %lx role %x\n", __func__,
1235 gfn, role.word);
1236 index = kvm_page_table_hashfn(gfn); 1306 index = kvm_page_table_hashfn(gfn);
1237 bucket = &vcpu->kvm->arch.mmu_page_hash[index]; 1307 bucket = &vcpu->kvm->arch.mmu_page_hash[index];
1238 hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link) 1308 hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link)
@@ -1249,14 +1319,13 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1249 set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); 1319 set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
1250 kvm_mmu_mark_parents_unsync(vcpu, sp); 1320 kvm_mmu_mark_parents_unsync(vcpu, sp);
1251 } 1321 }
1252 pgprintk("%s: found\n", __func__); 1322 trace_kvm_mmu_get_page(sp, false);
1253 return sp; 1323 return sp;
1254 } 1324 }
1255 ++vcpu->kvm->stat.mmu_cache_miss; 1325 ++vcpu->kvm->stat.mmu_cache_miss;
1256 sp = kvm_mmu_alloc_page(vcpu, parent_pte); 1326 sp = kvm_mmu_alloc_page(vcpu, parent_pte);
1257 if (!sp) 1327 if (!sp)
1258 return sp; 1328 return sp;
1259 pgprintk("%s: adding gfn %lx role %x\n", __func__, gfn, role.word);
1260 sp->gfn = gfn; 1329 sp->gfn = gfn;
1261 sp->role = role; 1330 sp->role = role;
1262 hlist_add_head(&sp->hash_link, bucket); 1331 hlist_add_head(&sp->hash_link, bucket);
@@ -1269,6 +1338,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1269 vcpu->arch.mmu.prefetch_page(vcpu, sp); 1338 vcpu->arch.mmu.prefetch_page(vcpu, sp);
1270 else 1339 else
1271 nonpaging_prefetch_page(vcpu, sp); 1340 nonpaging_prefetch_page(vcpu, sp);
1341 trace_kvm_mmu_get_page(sp, true);
1272 return sp; 1342 return sp;
1273} 1343}
1274 1344
@@ -1292,6 +1362,11 @@ static bool shadow_walk_okay(struct kvm_shadow_walk_iterator *iterator)
1292{ 1362{
1293 if (iterator->level < PT_PAGE_TABLE_LEVEL) 1363 if (iterator->level < PT_PAGE_TABLE_LEVEL)
1294 return false; 1364 return false;
1365
1366 if (iterator->level == PT_PAGE_TABLE_LEVEL)
1367 if (is_large_pte(*iterator->sptep))
1368 return false;
1369
1295 iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level); 1370 iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level);
1296 iterator->sptep = ((u64 *)__va(iterator->shadow_addr)) + iterator->index; 1371 iterator->sptep = ((u64 *)__va(iterator->shadow_addr)) + iterator->index;
1297 return true; 1372 return true;
@@ -1312,25 +1387,17 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm,
1312 1387
1313 pt = sp->spt; 1388 pt = sp->spt;
1314 1389
1315 if (sp->role.level == PT_PAGE_TABLE_LEVEL) {
1316 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
1317 if (is_shadow_present_pte(pt[i]))
1318 rmap_remove(kvm, &pt[i]);
1319 pt[i] = shadow_trap_nonpresent_pte;
1320 }
1321 return;
1322 }
1323
1324 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { 1390 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
1325 ent = pt[i]; 1391 ent = pt[i];
1326 1392
1327 if (is_shadow_present_pte(ent)) { 1393 if (is_shadow_present_pte(ent)) {
1328 if (!is_large_pte(ent)) { 1394 if (!is_last_spte(ent, sp->role.level)) {
1329 ent &= PT64_BASE_ADDR_MASK; 1395 ent &= PT64_BASE_ADDR_MASK;
1330 mmu_page_remove_parent_pte(page_header(ent), 1396 mmu_page_remove_parent_pte(page_header(ent),
1331 &pt[i]); 1397 &pt[i]);
1332 } else { 1398 } else {
1333 --kvm->stat.lpages; 1399 if (is_large_pte(ent))
1400 --kvm->stat.lpages;
1334 rmap_remove(kvm, &pt[i]); 1401 rmap_remove(kvm, &pt[i]);
1335 } 1402 }
1336 } 1403 }
@@ -1346,10 +1413,10 @@ static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
1346static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm) 1413static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm)
1347{ 1414{
1348 int i; 1415 int i;
1416 struct kvm_vcpu *vcpu;
1349 1417
1350 for (i = 0; i < KVM_MAX_VCPUS; ++i) 1418 kvm_for_each_vcpu(i, vcpu, kvm)
1351 if (kvm->vcpus[i]) 1419 vcpu->arch.last_pte_updated = NULL;
1352 kvm->vcpus[i]->arch.last_pte_updated = NULL;
1353} 1420}
1354 1421
1355static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) 1422static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
@@ -1368,7 +1435,7 @@ static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
1368 } 1435 }
1369 BUG_ON(!parent_pte); 1436 BUG_ON(!parent_pte);
1370 kvm_mmu_put_page(sp, parent_pte); 1437 kvm_mmu_put_page(sp, parent_pte);
1371 set_shadow_pte(parent_pte, shadow_trap_nonpresent_pte); 1438 __set_spte(parent_pte, shadow_trap_nonpresent_pte);
1372 } 1439 }
1373} 1440}
1374 1441
@@ -1400,6 +1467,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
1400static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) 1467static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
1401{ 1468{
1402 int ret; 1469 int ret;
1470
1471 trace_kvm_mmu_zap_page(sp);
1403 ++kvm->stat.mmu_shadow_zapped; 1472 ++kvm->stat.mmu_shadow_zapped;
1404 ret = mmu_zap_unsync_children(kvm, sp); 1473 ret = mmu_zap_unsync_children(kvm, sp);
1405 kvm_mmu_page_unlink_children(kvm, sp); 1474 kvm_mmu_page_unlink_children(kvm, sp);
@@ -1516,7 +1585,7 @@ static void mmu_convert_notrap(struct kvm_mmu_page *sp)
1516 1585
1517 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { 1586 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
1518 if (pt[i] == shadow_notrap_nonpresent_pte) 1587 if (pt[i] == shadow_notrap_nonpresent_pte)
1519 set_shadow_pte(&pt[i], shadow_trap_nonpresent_pte); 1588 __set_spte(&pt[i], shadow_trap_nonpresent_pte);
1520 } 1589 }
1521} 1590}
1522 1591
@@ -1646,6 +1715,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
1646 struct kvm_mmu_page *s; 1715 struct kvm_mmu_page *s;
1647 struct hlist_node *node, *n; 1716 struct hlist_node *node, *n;
1648 1717
1718 trace_kvm_mmu_unsync_page(sp);
1649 index = kvm_page_table_hashfn(sp->gfn); 1719 index = kvm_page_table_hashfn(sp->gfn);
1650 bucket = &vcpu->kvm->arch.mmu_page_hash[index]; 1720 bucket = &vcpu->kvm->arch.mmu_page_hash[index];
1651 /* don't unsync if pagetable is shadowed with multiple roles */ 1721 /* don't unsync if pagetable is shadowed with multiple roles */
@@ -1682,9 +1752,9 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
1682 return 0; 1752 return 0;
1683} 1753}
1684 1754
1685static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, 1755static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1686 unsigned pte_access, int user_fault, 1756 unsigned pte_access, int user_fault,
1687 int write_fault, int dirty, int largepage, 1757 int write_fault, int dirty, int level,
1688 gfn_t gfn, pfn_t pfn, bool speculative, 1758 gfn_t gfn, pfn_t pfn, bool speculative,
1689 bool can_unsync) 1759 bool can_unsync)
1690{ 1760{
@@ -1707,7 +1777,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
1707 spte |= shadow_nx_mask; 1777 spte |= shadow_nx_mask;
1708 if (pte_access & ACC_USER_MASK) 1778 if (pte_access & ACC_USER_MASK)
1709 spte |= shadow_user_mask; 1779 spte |= shadow_user_mask;
1710 if (largepage) 1780 if (level > PT_PAGE_TABLE_LEVEL)
1711 spte |= PT_PAGE_SIZE_MASK; 1781 spte |= PT_PAGE_SIZE_MASK;
1712 if (tdp_enabled) 1782 if (tdp_enabled)
1713 spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, 1783 spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
@@ -1718,7 +1788,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
1718 if ((pte_access & ACC_WRITE_MASK) 1788 if ((pte_access & ACC_WRITE_MASK)
1719 || (write_fault && !is_write_protection(vcpu) && !user_fault)) { 1789 || (write_fault && !is_write_protection(vcpu) && !user_fault)) {
1720 1790
1721 if (largepage && has_wrprotected_page(vcpu->kvm, gfn)) { 1791 if (level > PT_PAGE_TABLE_LEVEL &&
1792 has_wrprotected_page(vcpu->kvm, gfn, level)) {
1722 ret = 1; 1793 ret = 1;
1723 spte = shadow_trap_nonpresent_pte; 1794 spte = shadow_trap_nonpresent_pte;
1724 goto set_pte; 1795 goto set_pte;
@@ -1732,7 +1803,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
1732 * is responsibility of mmu_get_page / kvm_sync_page. 1803 * is responsibility of mmu_get_page / kvm_sync_page.
1733 * Same reasoning can be applied to dirty page accounting. 1804 * Same reasoning can be applied to dirty page accounting.
1734 */ 1805 */
1735 if (!can_unsync && is_writeble_pte(*shadow_pte)) 1806 if (!can_unsync && is_writeble_pte(*sptep))
1736 goto set_pte; 1807 goto set_pte;
1737 1808
1738 if (mmu_need_write_protect(vcpu, gfn, can_unsync)) { 1809 if (mmu_need_write_protect(vcpu, gfn, can_unsync)) {
@@ -1749,65 +1820,67 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
1749 mark_page_dirty(vcpu->kvm, gfn); 1820 mark_page_dirty(vcpu->kvm, gfn);
1750 1821
1751set_pte: 1822set_pte:
1752 set_shadow_pte(shadow_pte, spte); 1823 __set_spte(sptep, spte);
1753 return ret; 1824 return ret;
1754} 1825}
1755 1826
1756static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, 1827static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1757 unsigned pt_access, unsigned pte_access, 1828 unsigned pt_access, unsigned pte_access,
1758 int user_fault, int write_fault, int dirty, 1829 int user_fault, int write_fault, int dirty,
1759 int *ptwrite, int largepage, gfn_t gfn, 1830 int *ptwrite, int level, gfn_t gfn,
1760 pfn_t pfn, bool speculative) 1831 pfn_t pfn, bool speculative)
1761{ 1832{
1762 int was_rmapped = 0; 1833 int was_rmapped = 0;
1763 int was_writeble = is_writeble_pte(*shadow_pte); 1834 int was_writeble = is_writeble_pte(*sptep);
1764 int rmap_count; 1835 int rmap_count;
1765 1836
1766 pgprintk("%s: spte %llx access %x write_fault %d" 1837 pgprintk("%s: spte %llx access %x write_fault %d"
1767 " user_fault %d gfn %lx\n", 1838 " user_fault %d gfn %lx\n",
1768 __func__, *shadow_pte, pt_access, 1839 __func__, *sptep, pt_access,
1769 write_fault, user_fault, gfn); 1840 write_fault, user_fault, gfn);
1770 1841
1771 if (is_rmap_pte(*shadow_pte)) { 1842 if (is_rmap_spte(*sptep)) {
1772 /* 1843 /*
1773 * If we overwrite a PTE page pointer with a 2MB PMD, unlink 1844 * If we overwrite a PTE page pointer with a 2MB PMD, unlink
1774 * the parent of the now unreachable PTE. 1845 * the parent of the now unreachable PTE.
1775 */ 1846 */
1776 if (largepage && !is_large_pte(*shadow_pte)) { 1847 if (level > PT_PAGE_TABLE_LEVEL &&
1848 !is_large_pte(*sptep)) {
1777 struct kvm_mmu_page *child; 1849 struct kvm_mmu_page *child;
1778 u64 pte = *shadow_pte; 1850 u64 pte = *sptep;
1779 1851
1780 child = page_header(pte & PT64_BASE_ADDR_MASK); 1852 child = page_header(pte & PT64_BASE_ADDR_MASK);
1781 mmu_page_remove_parent_pte(child, shadow_pte); 1853 mmu_page_remove_parent_pte(child, sptep);
1782 } else if (pfn != spte_to_pfn(*shadow_pte)) { 1854 } else if (pfn != spte_to_pfn(*sptep)) {
1783 pgprintk("hfn old %lx new %lx\n", 1855 pgprintk("hfn old %lx new %lx\n",
1784 spte_to_pfn(*shadow_pte), pfn); 1856 spte_to_pfn(*sptep), pfn);
1785 rmap_remove(vcpu->kvm, shadow_pte); 1857 rmap_remove(vcpu->kvm, sptep);
1786 } else 1858 } else
1787 was_rmapped = 1; 1859 was_rmapped = 1;
1788 } 1860 }
1789 if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault, 1861
1790 dirty, largepage, gfn, pfn, speculative, true)) { 1862 if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault,
1863 dirty, level, gfn, pfn, speculative, true)) {
1791 if (write_fault) 1864 if (write_fault)
1792 *ptwrite = 1; 1865 *ptwrite = 1;
1793 kvm_x86_ops->tlb_flush(vcpu); 1866 kvm_x86_ops->tlb_flush(vcpu);
1794 } 1867 }
1795 1868
1796 pgprintk("%s: setting spte %llx\n", __func__, *shadow_pte); 1869 pgprintk("%s: setting spte %llx\n", __func__, *sptep);
1797 pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n", 1870 pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n",
1798 is_large_pte(*shadow_pte)? "2MB" : "4kB", 1871 is_large_pte(*sptep)? "2MB" : "4kB",
1799 is_present_pte(*shadow_pte)?"RW":"R", gfn, 1872 *sptep & PT_PRESENT_MASK ?"RW":"R", gfn,
1800 *shadow_pte, shadow_pte); 1873 *sptep, sptep);
1801 if (!was_rmapped && is_large_pte(*shadow_pte)) 1874 if (!was_rmapped && is_large_pte(*sptep))
1802 ++vcpu->kvm->stat.lpages; 1875 ++vcpu->kvm->stat.lpages;
1803 1876
1804 page_header_update_slot(vcpu->kvm, shadow_pte, gfn); 1877 page_header_update_slot(vcpu->kvm, sptep, gfn);
1805 if (!was_rmapped) { 1878 if (!was_rmapped) {
1806 rmap_count = rmap_add(vcpu, shadow_pte, gfn, largepage); 1879 rmap_count = rmap_add(vcpu, sptep, gfn);
1807 if (!is_rmap_pte(*shadow_pte)) 1880 if (!is_rmap_spte(*sptep))
1808 kvm_release_pfn_clean(pfn); 1881 kvm_release_pfn_clean(pfn);
1809 if (rmap_count > RMAP_RECYCLE_THRESHOLD) 1882 if (rmap_count > RMAP_RECYCLE_THRESHOLD)
1810 rmap_recycle(vcpu, gfn, largepage); 1883 rmap_recycle(vcpu, sptep, gfn);
1811 } else { 1884 } else {
1812 if (was_writeble) 1885 if (was_writeble)
1813 kvm_release_pfn_dirty(pfn); 1886 kvm_release_pfn_dirty(pfn);
@@ -1815,7 +1888,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
1815 kvm_release_pfn_clean(pfn); 1888 kvm_release_pfn_clean(pfn);
1816 } 1889 }
1817 if (speculative) { 1890 if (speculative) {
1818 vcpu->arch.last_pte_updated = shadow_pte; 1891 vcpu->arch.last_pte_updated = sptep;
1819 vcpu->arch.last_pte_gfn = gfn; 1892 vcpu->arch.last_pte_gfn = gfn;
1820 } 1893 }
1821} 1894}
@@ -1825,7 +1898,7 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
1825} 1898}
1826 1899
1827static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, 1900static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
1828 int largepage, gfn_t gfn, pfn_t pfn) 1901 int level, gfn_t gfn, pfn_t pfn)
1829{ 1902{
1830 struct kvm_shadow_walk_iterator iterator; 1903 struct kvm_shadow_walk_iterator iterator;
1831 struct kvm_mmu_page *sp; 1904 struct kvm_mmu_page *sp;
@@ -1833,11 +1906,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
1833 gfn_t pseudo_gfn; 1906 gfn_t pseudo_gfn;
1834 1907
1835 for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) { 1908 for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
1836 if (iterator.level == PT_PAGE_TABLE_LEVEL 1909 if (iterator.level == level) {
1837 || (largepage && iterator.level == PT_DIRECTORY_LEVEL)) {
1838 mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL, 1910 mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
1839 0, write, 1, &pt_write, 1911 0, write, 1, &pt_write,
1840 largepage, gfn, pfn, false); 1912 level, gfn, pfn, false);
1841 ++vcpu->stat.pf_fixed; 1913 ++vcpu->stat.pf_fixed;
1842 break; 1914 break;
1843 } 1915 }
@@ -1853,10 +1925,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
1853 return -ENOMEM; 1925 return -ENOMEM;
1854 } 1926 }
1855 1927
1856 set_shadow_pte(iterator.sptep, 1928 __set_spte(iterator.sptep,
1857 __pa(sp->spt) 1929 __pa(sp->spt)
1858 | PT_PRESENT_MASK | PT_WRITABLE_MASK 1930 | PT_PRESENT_MASK | PT_WRITABLE_MASK
1859 | shadow_user_mask | shadow_x_mask); 1931 | shadow_user_mask | shadow_x_mask);
1860 } 1932 }
1861 } 1933 }
1862 return pt_write; 1934 return pt_write;
@@ -1865,14 +1937,20 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
1865static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) 1937static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
1866{ 1938{
1867 int r; 1939 int r;
1868 int largepage = 0; 1940 int level;
1869 pfn_t pfn; 1941 pfn_t pfn;
1870 unsigned long mmu_seq; 1942 unsigned long mmu_seq;
1871 1943
1872 if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) { 1944 level = mapping_level(vcpu, gfn);
1873 gfn &= ~(KVM_PAGES_PER_HPAGE-1); 1945
1874 largepage = 1; 1946 /*
1875 } 1947 * This path builds a PAE pagetable - so we can map 2mb pages at
1948 * maximum. Therefore check if the level is larger than that.
1949 */
1950 if (level > PT_DIRECTORY_LEVEL)
1951 level = PT_DIRECTORY_LEVEL;
1952
1953 gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
1876 1954
1877 mmu_seq = vcpu->kvm->mmu_notifier_seq; 1955 mmu_seq = vcpu->kvm->mmu_notifier_seq;
1878 smp_rmb(); 1956 smp_rmb();
@@ -1888,7 +1966,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
1888 if (mmu_notifier_retry(vcpu, mmu_seq)) 1966 if (mmu_notifier_retry(vcpu, mmu_seq))
1889 goto out_unlock; 1967 goto out_unlock;
1890 kvm_mmu_free_some_pages(vcpu); 1968 kvm_mmu_free_some_pages(vcpu);
1891 r = __direct_map(vcpu, v, write, largepage, gfn, pfn); 1969 r = __direct_map(vcpu, v, write, level, gfn, pfn);
1892 spin_unlock(&vcpu->kvm->mmu_lock); 1970 spin_unlock(&vcpu->kvm->mmu_lock);
1893 1971
1894 1972
@@ -1954,6 +2032,7 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
1954 gfn_t root_gfn; 2032 gfn_t root_gfn;
1955 struct kvm_mmu_page *sp; 2033 struct kvm_mmu_page *sp;
1956 int direct = 0; 2034 int direct = 0;
2035 u64 pdptr;
1957 2036
1958 root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT; 2037 root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
1959 2038
@@ -1981,11 +2060,12 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
1981 2060
1982 ASSERT(!VALID_PAGE(root)); 2061 ASSERT(!VALID_PAGE(root));
1983 if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) { 2062 if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) {
1984 if (!is_present_pte(vcpu->arch.pdptrs[i])) { 2063 pdptr = kvm_pdptr_read(vcpu, i);
2064 if (!is_present_gpte(pdptr)) {
1985 vcpu->arch.mmu.pae_root[i] = 0; 2065 vcpu->arch.mmu.pae_root[i] = 0;
1986 continue; 2066 continue;
1987 } 2067 }
1988 root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT; 2068 root_gfn = pdptr >> PAGE_SHIFT;
1989 } else if (vcpu->arch.mmu.root_level == 0) 2069 } else if (vcpu->arch.mmu.root_level == 0)
1990 root_gfn = 0; 2070 root_gfn = 0;
1991 if (mmu_check_root(vcpu, root_gfn)) 2071 if (mmu_check_root(vcpu, root_gfn))
@@ -2062,7 +2142,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
2062{ 2142{
2063 pfn_t pfn; 2143 pfn_t pfn;
2064 int r; 2144 int r;
2065 int largepage = 0; 2145 int level;
2066 gfn_t gfn = gpa >> PAGE_SHIFT; 2146 gfn_t gfn = gpa >> PAGE_SHIFT;
2067 unsigned long mmu_seq; 2147 unsigned long mmu_seq;
2068 2148
@@ -2073,10 +2153,10 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
2073 if (r) 2153 if (r)
2074 return r; 2154 return r;
2075 2155
2076 if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) { 2156 level = mapping_level(vcpu, gfn);
2077 gfn &= ~(KVM_PAGES_PER_HPAGE-1); 2157
2078 largepage = 1; 2158 gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
2079 } 2159
2080 mmu_seq = vcpu->kvm->mmu_notifier_seq; 2160 mmu_seq = vcpu->kvm->mmu_notifier_seq;
2081 smp_rmb(); 2161 smp_rmb();
2082 pfn = gfn_to_pfn(vcpu->kvm, gfn); 2162 pfn = gfn_to_pfn(vcpu->kvm, gfn);
@@ -2089,7 +2169,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
2089 goto out_unlock; 2169 goto out_unlock;
2090 kvm_mmu_free_some_pages(vcpu); 2170 kvm_mmu_free_some_pages(vcpu);
2091 r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK, 2171 r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
2092 largepage, gfn, pfn); 2172 level, gfn, pfn);
2093 spin_unlock(&vcpu->kvm->mmu_lock); 2173 spin_unlock(&vcpu->kvm->mmu_lock);
2094 2174
2095 return r; 2175 return r;
@@ -2206,7 +2286,9 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level)
2206 context->rsvd_bits_mask[0][0] = exb_bit_rsvd | 2286 context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
2207 rsvd_bits(maxphyaddr, 51); 2287 rsvd_bits(maxphyaddr, 51);
2208 context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3]; 2288 context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3];
2209 context->rsvd_bits_mask[1][2] = context->rsvd_bits_mask[0][2]; 2289 context->rsvd_bits_mask[1][2] = exb_bit_rsvd |
2290 rsvd_bits(maxphyaddr, 51) |
2291 rsvd_bits(13, 29);
2210 context->rsvd_bits_mask[1][1] = exb_bit_rsvd | 2292 context->rsvd_bits_mask[1][1] = exb_bit_rsvd |
2211 rsvd_bits(maxphyaddr, 51) | 2293 rsvd_bits(maxphyaddr, 51) |
2212 rsvd_bits(13, 20); /* large page */ 2294 rsvd_bits(13, 20); /* large page */
@@ -2357,8 +2439,8 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
2357 spin_unlock(&vcpu->kvm->mmu_lock); 2439 spin_unlock(&vcpu->kvm->mmu_lock);
2358 if (r) 2440 if (r)
2359 goto out; 2441 goto out;
2442 /* set_cr3() should ensure TLB has been flushed */
2360 kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa); 2443 kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
2361 kvm_mmu_flush_tlb(vcpu);
2362out: 2444out:
2363 return r; 2445 return r;
2364} 2446}
@@ -2378,15 +2460,14 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
2378 2460
2379 pte = *spte; 2461 pte = *spte;
2380 if (is_shadow_present_pte(pte)) { 2462 if (is_shadow_present_pte(pte)) {
2381 if (sp->role.level == PT_PAGE_TABLE_LEVEL || 2463 if (is_last_spte(pte, sp->role.level))
2382 is_large_pte(pte))
2383 rmap_remove(vcpu->kvm, spte); 2464 rmap_remove(vcpu->kvm, spte);
2384 else { 2465 else {
2385 child = page_header(pte & PT64_BASE_ADDR_MASK); 2466 child = page_header(pte & PT64_BASE_ADDR_MASK);
2386 mmu_page_remove_parent_pte(child, spte); 2467 mmu_page_remove_parent_pte(child, spte);
2387 } 2468 }
2388 } 2469 }
2389 set_shadow_pte(spte, shadow_trap_nonpresent_pte); 2470 __set_spte(spte, shadow_trap_nonpresent_pte);
2390 if (is_large_pte(pte)) 2471 if (is_large_pte(pte))
2391 --vcpu->kvm->stat.lpages; 2472 --vcpu->kvm->stat.lpages;
2392} 2473}
@@ -2397,11 +2478,8 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
2397 const void *new) 2478 const void *new)
2398{ 2479{
2399 if (sp->role.level != PT_PAGE_TABLE_LEVEL) { 2480 if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
2400 if (!vcpu->arch.update_pte.largepage || 2481 ++vcpu->kvm->stat.mmu_pde_zapped;
2401 sp->role.glevels == PT32_ROOT_LEVEL) { 2482 return;
2402 ++vcpu->kvm->stat.mmu_pde_zapped;
2403 return;
2404 }
2405 } 2483 }
2406 2484
2407 ++vcpu->kvm->stat.mmu_pte_updated; 2485 ++vcpu->kvm->stat.mmu_pte_updated;
@@ -2447,8 +2525,6 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
2447 u64 gpte = 0; 2525 u64 gpte = 0;
2448 pfn_t pfn; 2526 pfn_t pfn;
2449 2527
2450 vcpu->arch.update_pte.largepage = 0;
2451
2452 if (bytes != 4 && bytes != 8) 2528 if (bytes != 4 && bytes != 8)
2453 return; 2529 return;
2454 2530
@@ -2472,14 +2548,10 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
2472 if ((bytes == 4) && (gpa % 4 == 0)) 2548 if ((bytes == 4) && (gpa % 4 == 0))
2473 memcpy((void *)&gpte, new, 4); 2549 memcpy((void *)&gpte, new, 4);
2474 } 2550 }
2475 if (!is_present_pte(gpte)) 2551 if (!is_present_gpte(gpte))
2476 return; 2552 return;
2477 gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; 2553 gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
2478 2554
2479 if (is_large_pte(gpte) && is_largepage_backed(vcpu, gfn)) {
2480 gfn &= ~(KVM_PAGES_PER_HPAGE-1);
2481 vcpu->arch.update_pte.largepage = 1;
2482 }
2483 vcpu->arch.update_pte.mmu_seq = vcpu->kvm->mmu_notifier_seq; 2555 vcpu->arch.update_pte.mmu_seq = vcpu->kvm->mmu_notifier_seq;
2484 smp_rmb(); 2556 smp_rmb();
2485 pfn = gfn_to_pfn(vcpu->kvm, gfn); 2557 pfn = gfn_to_pfn(vcpu->kvm, gfn);
@@ -2622,6 +2694,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
2622 gpa_t gpa; 2694 gpa_t gpa;
2623 int r; 2695 int r;
2624 2696
2697 if (tdp_enabled)
2698 return 0;
2699
2625 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); 2700 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
2626 2701
2627 spin_lock(&vcpu->kvm->mmu_lock); 2702 spin_lock(&vcpu->kvm->mmu_lock);
@@ -2633,7 +2708,8 @@ EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
2633 2708
2634void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) 2709void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
2635{ 2710{
2636 while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES) { 2711 while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES &&
2712 !list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
2637 struct kvm_mmu_page *sp; 2713 struct kvm_mmu_page *sp;
2638 2714
2639 sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev, 2715 sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev,
@@ -2670,8 +2746,9 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
2670 ++vcpu->stat.mmio_exits; 2746 ++vcpu->stat.mmio_exits;
2671 return 0; 2747 return 0;
2672 case EMULATE_FAIL: 2748 case EMULATE_FAIL:
2673 kvm_report_emulation_failure(vcpu, "pagetable"); 2749 vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
2674 return 1; 2750 vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
2751 return 0;
2675 default: 2752 default:
2676 BUG(); 2753 BUG();
2677 } 2754 }
@@ -2712,12 +2789,6 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
2712 2789
2713 ASSERT(vcpu); 2790 ASSERT(vcpu);
2714 2791
2715 if (vcpu->kvm->arch.n_requested_mmu_pages)
2716 vcpu->kvm->arch.n_free_mmu_pages =
2717 vcpu->kvm->arch.n_requested_mmu_pages;
2718 else
2719 vcpu->kvm->arch.n_free_mmu_pages =
2720 vcpu->kvm->arch.n_alloc_mmu_pages;
2721 /* 2792 /*
2722 * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64. 2793 * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
2723 * Therefore we need to allocate shadow page tables in the first 2794 * Therefore we need to allocate shadow page tables in the first
@@ -3029,6 +3100,24 @@ out:
3029 return r; 3100 return r;
3030} 3101}
3031 3102
3103int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
3104{
3105 struct kvm_shadow_walk_iterator iterator;
3106 int nr_sptes = 0;
3107
3108 spin_lock(&vcpu->kvm->mmu_lock);
3109 for_each_shadow_entry(vcpu, addr, iterator) {
3110 sptes[iterator.level-1] = *iterator.sptep;
3111 nr_sptes++;
3112 if (!is_shadow_present_pte(*iterator.sptep))
3113 break;
3114 }
3115 spin_unlock(&vcpu->kvm->mmu_lock);
3116
3117 return nr_sptes;
3118}
3119EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);
3120
3032#ifdef AUDIT 3121#ifdef AUDIT
3033 3122
3034static const char *audit_msg; 3123static const char *audit_msg;
@@ -3041,6 +3130,54 @@ static gva_t canonicalize(gva_t gva)
3041 return gva; 3130 return gva;
3042} 3131}
3043 3132
3133
3134typedef void (*inspect_spte_fn) (struct kvm *kvm, struct kvm_mmu_page *sp,
3135 u64 *sptep);
3136
3137static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp,
3138 inspect_spte_fn fn)
3139{
3140 int i;
3141
3142 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
3143 u64 ent = sp->spt[i];
3144
3145 if (is_shadow_present_pte(ent)) {
3146 if (!is_last_spte(ent, sp->role.level)) {
3147 struct kvm_mmu_page *child;
3148 child = page_header(ent & PT64_BASE_ADDR_MASK);
3149 __mmu_spte_walk(kvm, child, fn);
3150 } else
3151 fn(kvm, sp, &sp->spt[i]);
3152 }
3153 }
3154}
3155
3156static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
3157{
3158 int i;
3159 struct kvm_mmu_page *sp;
3160
3161 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
3162 return;
3163 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
3164 hpa_t root = vcpu->arch.mmu.root_hpa;
3165 sp = page_header(root);
3166 __mmu_spte_walk(vcpu->kvm, sp, fn);
3167 return;
3168 }
3169 for (i = 0; i < 4; ++i) {
3170 hpa_t root = vcpu->arch.mmu.pae_root[i];
3171
3172 if (root && VALID_PAGE(root)) {
3173 root &= PT64_BASE_ADDR_MASK;
3174 sp = page_header(root);
3175 __mmu_spte_walk(vcpu->kvm, sp, fn);
3176 }
3177 }
3178 return;
3179}
3180
3044static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, 3181static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
3045 gva_t va, int level) 3182 gva_t va, int level)
3046{ 3183{
@@ -3055,20 +3192,19 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
3055 continue; 3192 continue;
3056 3193
3057 va = canonicalize(va); 3194 va = canonicalize(va);
3058 if (level > 1) { 3195 if (is_shadow_present_pte(ent) && !is_last_spte(ent, level))
3059 if (ent == shadow_notrap_nonpresent_pte) 3196 audit_mappings_page(vcpu, ent, va, level - 1);
3060 printk(KERN_ERR "audit: (%s) nontrapping pte" 3197 else {
3061 " in nonleaf level: levels %d gva %lx"
3062 " level %d pte %llx\n", audit_msg,
3063 vcpu->arch.mmu.root_level, va, level, ent);
3064 else
3065 audit_mappings_page(vcpu, ent, va, level - 1);
3066 } else {
3067 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va); 3198 gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va);
3068 gfn_t gfn = gpa >> PAGE_SHIFT; 3199 gfn_t gfn = gpa >> PAGE_SHIFT;
3069 pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn); 3200 pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn);
3070 hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT; 3201 hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT;
3071 3202
3203 if (is_error_pfn(pfn)) {
3204 kvm_release_pfn_clean(pfn);
3205 continue;
3206 }
3207
3072 if (is_shadow_present_pte(ent) 3208 if (is_shadow_present_pte(ent)
3073 && (ent & PT64_BASE_ADDR_MASK) != hpa) 3209 && (ent & PT64_BASE_ADDR_MASK) != hpa)
3074 printk(KERN_ERR "xx audit error: (%s) levels %d" 3210 printk(KERN_ERR "xx audit error: (%s) levels %d"
@@ -3122,7 +3258,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
3122 d = (struct kvm_rmap_desc *)(*rmapp & ~1ul); 3258 d = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
3123 while (d) { 3259 while (d) {
3124 for (k = 0; k < RMAP_EXT; ++k) 3260 for (k = 0; k < RMAP_EXT; ++k)
3125 if (d->shadow_ptes[k]) 3261 if (d->sptes[k])
3126 ++nmaps; 3262 ++nmaps;
3127 else 3263 else
3128 break; 3264 break;
@@ -3133,9 +3269,48 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
3133 return nmaps; 3269 return nmaps;
3134} 3270}
3135 3271
3136static int count_writable_mappings(struct kvm_vcpu *vcpu) 3272void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep)
3273{
3274 unsigned long *rmapp;
3275 struct kvm_mmu_page *rev_sp;
3276 gfn_t gfn;
3277
3278 if (*sptep & PT_WRITABLE_MASK) {
3279 rev_sp = page_header(__pa(sptep));
3280 gfn = rev_sp->gfns[sptep - rev_sp->spt];
3281
3282 if (!gfn_to_memslot(kvm, gfn)) {
3283 if (!printk_ratelimit())
3284 return;
3285 printk(KERN_ERR "%s: no memslot for gfn %ld\n",
3286 audit_msg, gfn);
3287 printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n",
3288 audit_msg, sptep - rev_sp->spt,
3289 rev_sp->gfn);
3290 dump_stack();
3291 return;
3292 }
3293
3294 rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt],
3295 is_large_pte(*sptep));
3296 if (!*rmapp) {
3297 if (!printk_ratelimit())
3298 return;
3299 printk(KERN_ERR "%s: no rmap for writable spte %llx\n",
3300 audit_msg, *sptep);
3301 dump_stack();
3302 }
3303 }
3304
3305}
3306
3307void audit_writable_sptes_have_rmaps(struct kvm_vcpu *vcpu)
3308{
3309 mmu_spte_walk(vcpu, inspect_spte_has_rmap);
3310}
3311
3312static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu)
3137{ 3313{
3138 int nmaps = 0;
3139 struct kvm_mmu_page *sp; 3314 struct kvm_mmu_page *sp;
3140 int i; 3315 int i;
3141 3316
@@ -3152,20 +3327,16 @@ static int count_writable_mappings(struct kvm_vcpu *vcpu)
3152 continue; 3327 continue;
3153 if (!(ent & PT_WRITABLE_MASK)) 3328 if (!(ent & PT_WRITABLE_MASK))
3154 continue; 3329 continue;
3155 ++nmaps; 3330 inspect_spte_has_rmap(vcpu->kvm, sp, &pt[i]);
3156 } 3331 }
3157 } 3332 }
3158 return nmaps; 3333 return;
3159} 3334}
3160 3335
3161static void audit_rmap(struct kvm_vcpu *vcpu) 3336static void audit_rmap(struct kvm_vcpu *vcpu)
3162{ 3337{
3163 int n_rmap = count_rmaps(vcpu); 3338 check_writable_mappings_rmap(vcpu);
3164 int n_actual = count_writable_mappings(vcpu); 3339 count_rmaps(vcpu);
3165
3166 if (n_rmap != n_actual)
3167 printk(KERN_ERR "%s: (%s) rmap %d actual %d\n",
3168 __func__, audit_msg, n_rmap, n_actual);
3169} 3340}
3170 3341
3171static void audit_write_protection(struct kvm_vcpu *vcpu) 3342static void audit_write_protection(struct kvm_vcpu *vcpu)
@@ -3173,20 +3344,28 @@ static void audit_write_protection(struct kvm_vcpu *vcpu)
3173 struct kvm_mmu_page *sp; 3344 struct kvm_mmu_page *sp;
3174 struct kvm_memory_slot *slot; 3345 struct kvm_memory_slot *slot;
3175 unsigned long *rmapp; 3346 unsigned long *rmapp;
3347 u64 *spte;
3176 gfn_t gfn; 3348 gfn_t gfn;
3177 3349
3178 list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { 3350 list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
3179 if (sp->role.direct) 3351 if (sp->role.direct)
3180 continue; 3352 continue;
3353 if (sp->unsync)
3354 continue;
3181 3355
3182 gfn = unalias_gfn(vcpu->kvm, sp->gfn); 3356 gfn = unalias_gfn(vcpu->kvm, sp->gfn);
3183 slot = gfn_to_memslot_unaliased(vcpu->kvm, sp->gfn); 3357 slot = gfn_to_memslot_unaliased(vcpu->kvm, sp->gfn);
3184 rmapp = &slot->rmap[gfn - slot->base_gfn]; 3358 rmapp = &slot->rmap[gfn - slot->base_gfn];
3185 if (*rmapp) 3359
3186 printk(KERN_ERR "%s: (%s) shadow page has writable" 3360 spte = rmap_next(vcpu->kvm, rmapp, NULL);
3187 " mappings: gfn %lx role %x\n", 3361 while (spte) {
3362 if (*spte & PT_WRITABLE_MASK)
3363 printk(KERN_ERR "%s: (%s) shadow page has "
3364 "writable mappings: gfn %lx role %x\n",
3188 __func__, audit_msg, sp->gfn, 3365 __func__, audit_msg, sp->gfn,
3189 sp->role.word); 3366 sp->role.word);
3367 spte = rmap_next(vcpu->kvm, rmapp, spte);
3368 }
3190 } 3369 }
3191} 3370}
3192 3371
@@ -3198,7 +3377,9 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg)
3198 audit_msg = msg; 3377 audit_msg = msg;
3199 audit_rmap(vcpu); 3378 audit_rmap(vcpu);
3200 audit_write_protection(vcpu); 3379 audit_write_protection(vcpu);
3201 audit_mappings(vcpu); 3380 if (strcmp("pre pte write", audit_msg) != 0)
3381 audit_mappings(vcpu);
3382 audit_writable_sptes_have_rmaps(vcpu);
3202 dbg = olddbg; 3383 dbg = olddbg;
3203} 3384}
3204 3385
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 3494a2fb136e..61a1b3884b49 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -37,6 +37,8 @@
37#define PT32_ROOT_LEVEL 2 37#define PT32_ROOT_LEVEL 2
38#define PT32E_ROOT_LEVEL 3 38#define PT32E_ROOT_LEVEL 3
39 39
40int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
41
40static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) 42static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
41{ 43{
42 if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES)) 44 if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
@@ -75,7 +77,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
75 return vcpu->arch.cr0 & X86_CR0_PG; 77 return vcpu->arch.cr0 & X86_CR0_PG;
76} 78}
77 79
78static inline int is_present_pte(unsigned long pte) 80static inline int is_present_gpte(unsigned long pte)
79{ 81{
80 return pte & PT_PRESENT_MASK; 82 return pte & PT_PRESENT_MASK;
81} 83}
diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h
new file mode 100644
index 000000000000..3e4a5c6ca2a9
--- /dev/null
+++ b/arch/x86/kvm/mmutrace.h
@@ -0,0 +1,220 @@
1#if !defined(_TRACE_KVMMMU_H) || defined(TRACE_HEADER_MULTI_READ)
2#define _TRACE_KVMMMU_H
3
4#include <linux/tracepoint.h>
5#include <linux/ftrace_event.h>
6
7#undef TRACE_SYSTEM
8#define TRACE_SYSTEM kvmmmu
9#define TRACE_INCLUDE_PATH .
10#define TRACE_INCLUDE_FILE mmutrace
11
12#define KVM_MMU_PAGE_FIELDS \
13 __field(__u64, gfn) \
14 __field(__u32, role) \
15 __field(__u32, root_count) \
16 __field(__u32, unsync)
17
18#define KVM_MMU_PAGE_ASSIGN(sp) \
19 __entry->gfn = sp->gfn; \
20 __entry->role = sp->role.word; \
21 __entry->root_count = sp->root_count; \
22 __entry->unsync = sp->unsync;
23
24#define KVM_MMU_PAGE_PRINTK() ({ \
25 const char *ret = p->buffer + p->len; \
26 static const char *access_str[] = { \
27 "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" \
28 }; \
29 union kvm_mmu_page_role role; \
30 \
31 role.word = __entry->role; \
32 \
33 trace_seq_printf(p, "sp gfn %llx %u/%u q%u%s %s%s %spge" \
34 " %snxe root %u %s%c", \
35 __entry->gfn, role.level, role.glevels, \
36 role.quadrant, \
37 role.direct ? " direct" : "", \
38 access_str[role.access], \
39 role.invalid ? " invalid" : "", \
40 role.cr4_pge ? "" : "!", \
41 role.nxe ? "" : "!", \
42 __entry->root_count, \
43 __entry->unsync ? "unsync" : "sync", 0); \
44 ret; \
45 })
46
47#define kvm_mmu_trace_pferr_flags \
48 { PFERR_PRESENT_MASK, "P" }, \
49 { PFERR_WRITE_MASK, "W" }, \
50 { PFERR_USER_MASK, "U" }, \
51 { PFERR_RSVD_MASK, "RSVD" }, \
52 { PFERR_FETCH_MASK, "F" }
53
54/*
55 * A pagetable walk has started
56 */
57TRACE_EVENT(
58 kvm_mmu_pagetable_walk,
59 TP_PROTO(u64 addr, int write_fault, int user_fault, int fetch_fault),
60 TP_ARGS(addr, write_fault, user_fault, fetch_fault),
61
62 TP_STRUCT__entry(
63 __field(__u64, addr)
64 __field(__u32, pferr)
65 ),
66
67 TP_fast_assign(
68 __entry->addr = addr;
69 __entry->pferr = (!!write_fault << 1) | (!!user_fault << 2)
70 | (!!fetch_fault << 4);
71 ),
72
73 TP_printk("addr %llx pferr %x %s", __entry->addr, __entry->pferr,
74 __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags))
75);
76
77
78/* We just walked a paging element */
79TRACE_EVENT(
80 kvm_mmu_paging_element,
81 TP_PROTO(u64 pte, int level),
82 TP_ARGS(pte, level),
83
84 TP_STRUCT__entry(
85 __field(__u64, pte)
86 __field(__u32, level)
87 ),
88
89 TP_fast_assign(
90 __entry->pte = pte;
91 __entry->level = level;
92 ),
93
94 TP_printk("pte %llx level %u", __entry->pte, __entry->level)
95);
96
97/* We set a pte accessed bit */
98TRACE_EVENT(
99 kvm_mmu_set_accessed_bit,
100 TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),
101 TP_ARGS(table_gfn, index, size),
102
103 TP_STRUCT__entry(
104 __field(__u64, gpa)
105 ),
106
107 TP_fast_assign(
108 __entry->gpa = ((u64)table_gfn << PAGE_SHIFT)
109 + index * size;
110 ),
111
112 TP_printk("gpa %llx", __entry->gpa)
113);
114
115/* We set a pte dirty bit */
116TRACE_EVENT(
117 kvm_mmu_set_dirty_bit,
118 TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),
119 TP_ARGS(table_gfn, index, size),
120
121 TP_STRUCT__entry(
122 __field(__u64, gpa)
123 ),
124
125 TP_fast_assign(
126 __entry->gpa = ((u64)table_gfn << PAGE_SHIFT)
127 + index * size;
128 ),
129
130 TP_printk("gpa %llx", __entry->gpa)
131);
132
133TRACE_EVENT(
134 kvm_mmu_walker_error,
135 TP_PROTO(u32 pferr),
136 TP_ARGS(pferr),
137
138 TP_STRUCT__entry(
139 __field(__u32, pferr)
140 ),
141
142 TP_fast_assign(
143 __entry->pferr = pferr;
144 ),
145
146 TP_printk("pferr %x %s", __entry->pferr,
147 __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags))
148);
149
150TRACE_EVENT(
151 kvm_mmu_get_page,
152 TP_PROTO(struct kvm_mmu_page *sp, bool created),
153 TP_ARGS(sp, created),
154
155 TP_STRUCT__entry(
156 KVM_MMU_PAGE_FIELDS
157 __field(bool, created)
158 ),
159
160 TP_fast_assign(
161 KVM_MMU_PAGE_ASSIGN(sp)
162 __entry->created = created;
163 ),
164
165 TP_printk("%s %s", KVM_MMU_PAGE_PRINTK(),
166 __entry->created ? "new" : "existing")
167);
168
169TRACE_EVENT(
170 kvm_mmu_sync_page,
171 TP_PROTO(struct kvm_mmu_page *sp),
172 TP_ARGS(sp),
173
174 TP_STRUCT__entry(
175 KVM_MMU_PAGE_FIELDS
176 ),
177
178 TP_fast_assign(
179 KVM_MMU_PAGE_ASSIGN(sp)
180 ),
181
182 TP_printk("%s", KVM_MMU_PAGE_PRINTK())
183);
184
185TRACE_EVENT(
186 kvm_mmu_unsync_page,
187 TP_PROTO(struct kvm_mmu_page *sp),
188 TP_ARGS(sp),
189
190 TP_STRUCT__entry(
191 KVM_MMU_PAGE_FIELDS
192 ),
193
194 TP_fast_assign(
195 KVM_MMU_PAGE_ASSIGN(sp)
196 ),
197
198 TP_printk("%s", KVM_MMU_PAGE_PRINTK())
199);
200
201TRACE_EVENT(
202 kvm_mmu_zap_page,
203 TP_PROTO(struct kvm_mmu_page *sp),
204 TP_ARGS(sp),
205
206 TP_STRUCT__entry(
207 KVM_MMU_PAGE_FIELDS
208 ),
209
210 TP_fast_assign(
211 KVM_MMU_PAGE_ASSIGN(sp)
212 ),
213
214 TP_printk("%s", KVM_MMU_PAGE_PRINTK())
215);
216
217#endif /* _TRACE_KVMMMU_H */
218
219/* This part must be outside protection */
220#include <trace/define_trace.h>
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 67785f635399..d2fec9c12d22 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -27,7 +27,8 @@
27 #define guest_walker guest_walker64 27 #define guest_walker guest_walker64
28 #define FNAME(name) paging##64_##name 28 #define FNAME(name) paging##64_##name
29 #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK 29 #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
30 #define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK 30 #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl)
31 #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl)
31 #define PT_INDEX(addr, level) PT64_INDEX(addr, level) 32 #define PT_INDEX(addr, level) PT64_INDEX(addr, level)
32 #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level) 33 #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
33 #define PT_LEVEL_BITS PT64_LEVEL_BITS 34 #define PT_LEVEL_BITS PT64_LEVEL_BITS
@@ -43,7 +44,8 @@
43 #define guest_walker guest_walker32 44 #define guest_walker guest_walker32
44 #define FNAME(name) paging##32_##name 45 #define FNAME(name) paging##32_##name
45 #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK 46 #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
46 #define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK 47 #define PT_LVL_ADDR_MASK(lvl) PT32_LVL_ADDR_MASK(lvl)
48 #define PT_LVL_OFFSET_MASK(lvl) PT32_LVL_OFFSET_MASK(lvl)
47 #define PT_INDEX(addr, level) PT32_INDEX(addr, level) 49 #define PT_INDEX(addr, level) PT32_INDEX(addr, level)
48 #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level) 50 #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
49 #define PT_LEVEL_BITS PT32_LEVEL_BITS 51 #define PT_LEVEL_BITS PT32_LEVEL_BITS
@@ -53,8 +55,8 @@
53 #error Invalid PTTYPE value 55 #error Invalid PTTYPE value
54#endif 56#endif
55 57
56#define gpte_to_gfn FNAME(gpte_to_gfn) 58#define gpte_to_gfn_lvl FNAME(gpte_to_gfn_lvl)
57#define gpte_to_gfn_pde FNAME(gpte_to_gfn_pde) 59#define gpte_to_gfn(pte) gpte_to_gfn_lvl((pte), PT_PAGE_TABLE_LEVEL)
58 60
59/* 61/*
60 * The guest_walker structure emulates the behavior of the hardware page 62 * The guest_walker structure emulates the behavior of the hardware page
@@ -71,14 +73,9 @@ struct guest_walker {
71 u32 error_code; 73 u32 error_code;
72}; 74};
73 75
74static gfn_t gpte_to_gfn(pt_element_t gpte) 76static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl)
75{ 77{
76 return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; 78 return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT;
77}
78
79static gfn_t gpte_to_gfn_pde(pt_element_t gpte)
80{
81 return (gpte & PT_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
82} 79}
83 80
84static bool FNAME(cmpxchg_gpte)(struct kvm *kvm, 81static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
@@ -125,14 +122,16 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
125 gpa_t pte_gpa; 122 gpa_t pte_gpa;
126 int rsvd_fault = 0; 123 int rsvd_fault = 0;
127 124
128 pgprintk("%s: addr %lx\n", __func__, addr); 125 trace_kvm_mmu_pagetable_walk(addr, write_fault, user_fault,
126 fetch_fault);
129walk: 127walk:
130 walker->level = vcpu->arch.mmu.root_level; 128 walker->level = vcpu->arch.mmu.root_level;
131 pte = vcpu->arch.cr3; 129 pte = vcpu->arch.cr3;
132#if PTTYPE == 64 130#if PTTYPE == 64
133 if (!is_long_mode(vcpu)) { 131 if (!is_long_mode(vcpu)) {
134 pte = vcpu->arch.pdptrs[(addr >> 30) & 3]; 132 pte = kvm_pdptr_read(vcpu, (addr >> 30) & 3);
135 if (!is_present_pte(pte)) 133 trace_kvm_mmu_paging_element(pte, walker->level);
134 if (!is_present_gpte(pte))
136 goto not_present; 135 goto not_present;
137 --walker->level; 136 --walker->level;
138 } 137 }
@@ -150,12 +149,11 @@ walk:
150 pte_gpa += index * sizeof(pt_element_t); 149 pte_gpa += index * sizeof(pt_element_t);
151 walker->table_gfn[walker->level - 1] = table_gfn; 150 walker->table_gfn[walker->level - 1] = table_gfn;
152 walker->pte_gpa[walker->level - 1] = pte_gpa; 151 walker->pte_gpa[walker->level - 1] = pte_gpa;
153 pgprintk("%s: table_gfn[%d] %lx\n", __func__,
154 walker->level - 1, table_gfn);
155 152
156 kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); 153 kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
154 trace_kvm_mmu_paging_element(pte, walker->level);
157 155
158 if (!is_present_pte(pte)) 156 if (!is_present_gpte(pte))
159 goto not_present; 157 goto not_present;
160 158
161 rsvd_fault = is_rsvd_bits_set(vcpu, pte, walker->level); 159 rsvd_fault = is_rsvd_bits_set(vcpu, pte, walker->level);
@@ -175,6 +173,8 @@ walk:
175#endif 173#endif
176 174
177 if (!(pte & PT_ACCESSED_MASK)) { 175 if (!(pte & PT_ACCESSED_MASK)) {
176 trace_kvm_mmu_set_accessed_bit(table_gfn, index,
177 sizeof(pte));
178 mark_page_dirty(vcpu->kvm, table_gfn); 178 mark_page_dirty(vcpu->kvm, table_gfn);
179 if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, 179 if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn,
180 index, pte, pte|PT_ACCESSED_MASK)) 180 index, pte, pte|PT_ACCESSED_MASK))
@@ -186,18 +186,24 @@ walk:
186 186
187 walker->ptes[walker->level - 1] = pte; 187 walker->ptes[walker->level - 1] = pte;
188 188
189 if (walker->level == PT_PAGE_TABLE_LEVEL) { 189 if ((walker->level == PT_PAGE_TABLE_LEVEL) ||
190 walker->gfn = gpte_to_gfn(pte); 190 ((walker->level == PT_DIRECTORY_LEVEL) &&
191 break; 191 (pte & PT_PAGE_SIZE_MASK) &&
192 } 192 (PTTYPE == 64 || is_pse(vcpu))) ||
193 193 ((walker->level == PT_PDPE_LEVEL) &&
194 if (walker->level == PT_DIRECTORY_LEVEL 194 (pte & PT_PAGE_SIZE_MASK) &&
195 && (pte & PT_PAGE_SIZE_MASK) 195 is_long_mode(vcpu))) {
196 && (PTTYPE == 64 || is_pse(vcpu))) { 196 int lvl = walker->level;
197 walker->gfn = gpte_to_gfn_pde(pte); 197
198 walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL); 198 walker->gfn = gpte_to_gfn_lvl(pte, lvl);
199 if (PTTYPE == 32 && is_cpuid_PSE36()) 199 walker->gfn += (addr & PT_LVL_OFFSET_MASK(lvl))
200 >> PAGE_SHIFT;
201
202 if (PTTYPE == 32 &&
203 walker->level == PT_DIRECTORY_LEVEL &&
204 is_cpuid_PSE36())
200 walker->gfn += pse36_gfn_delta(pte); 205 walker->gfn += pse36_gfn_delta(pte);
206
201 break; 207 break;
202 } 208 }
203 209
@@ -205,9 +211,10 @@ walk:
205 --walker->level; 211 --walker->level;
206 } 212 }
207 213
208 if (write_fault && !is_dirty_pte(pte)) { 214 if (write_fault && !is_dirty_gpte(pte)) {
209 bool ret; 215 bool ret;
210 216
217 trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
211 mark_page_dirty(vcpu->kvm, table_gfn); 218 mark_page_dirty(vcpu->kvm, table_gfn);
212 ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, 219 ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte,
213 pte|PT_DIRTY_MASK); 220 pte|PT_DIRTY_MASK);
@@ -239,6 +246,7 @@ err:
239 walker->error_code |= PFERR_FETCH_MASK; 246 walker->error_code |= PFERR_FETCH_MASK;
240 if (rsvd_fault) 247 if (rsvd_fault)
241 walker->error_code |= PFERR_RSVD_MASK; 248 walker->error_code |= PFERR_RSVD_MASK;
249 trace_kvm_mmu_walker_error(walker->error_code);
242 return 0; 250 return 0;
243} 251}
244 252
@@ -248,12 +256,11 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
248 pt_element_t gpte; 256 pt_element_t gpte;
249 unsigned pte_access; 257 unsigned pte_access;
250 pfn_t pfn; 258 pfn_t pfn;
251 int largepage = vcpu->arch.update_pte.largepage;
252 259
253 gpte = *(const pt_element_t *)pte; 260 gpte = *(const pt_element_t *)pte;
254 if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { 261 if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
255 if (!is_present_pte(gpte)) 262 if (!is_present_gpte(gpte))
256 set_shadow_pte(spte, shadow_notrap_nonpresent_pte); 263 __set_spte(spte, shadow_notrap_nonpresent_pte);
257 return; 264 return;
258 } 265 }
259 pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); 266 pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte);
@@ -267,7 +274,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
267 return; 274 return;
268 kvm_get_pfn(pfn); 275 kvm_get_pfn(pfn);
269 mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0, 276 mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
270 gpte & PT_DIRTY_MASK, NULL, largepage, 277 gpte & PT_DIRTY_MASK, NULL, PT_PAGE_TABLE_LEVEL,
271 gpte_to_gfn(gpte), pfn, true); 278 gpte_to_gfn(gpte), pfn, true);
272} 279}
273 280
@@ -276,7 +283,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
276 */ 283 */
277static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, 284static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
278 struct guest_walker *gw, 285 struct guest_walker *gw,
279 int user_fault, int write_fault, int largepage, 286 int user_fault, int write_fault, int hlevel,
280 int *ptwrite, pfn_t pfn) 287 int *ptwrite, pfn_t pfn)
281{ 288{
282 unsigned access = gw->pt_access; 289 unsigned access = gw->pt_access;
@@ -289,19 +296,18 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
289 pt_element_t curr_pte; 296 pt_element_t curr_pte;
290 struct kvm_shadow_walk_iterator iterator; 297 struct kvm_shadow_walk_iterator iterator;
291 298
292 if (!is_present_pte(gw->ptes[gw->level - 1])) 299 if (!is_present_gpte(gw->ptes[gw->level - 1]))
293 return NULL; 300 return NULL;
294 301
295 for_each_shadow_entry(vcpu, addr, iterator) { 302 for_each_shadow_entry(vcpu, addr, iterator) {
296 level = iterator.level; 303 level = iterator.level;
297 sptep = iterator.sptep; 304 sptep = iterator.sptep;
298 if (level == PT_PAGE_TABLE_LEVEL 305 if (iterator.level == hlevel) {
299 || (largepage && level == PT_DIRECTORY_LEVEL)) {
300 mmu_set_spte(vcpu, sptep, access, 306 mmu_set_spte(vcpu, sptep, access,
301 gw->pte_access & access, 307 gw->pte_access & access,
302 user_fault, write_fault, 308 user_fault, write_fault,
303 gw->ptes[gw->level-1] & PT_DIRTY_MASK, 309 gw->ptes[gw->level-1] & PT_DIRTY_MASK,
304 ptwrite, largepage, 310 ptwrite, level,
305 gw->gfn, pfn, false); 311 gw->gfn, pfn, false);
306 break; 312 break;
307 } 313 }
@@ -311,16 +317,19 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
311 317
312 if (is_large_pte(*sptep)) { 318 if (is_large_pte(*sptep)) {
313 rmap_remove(vcpu->kvm, sptep); 319 rmap_remove(vcpu->kvm, sptep);
314 set_shadow_pte(sptep, shadow_trap_nonpresent_pte); 320 __set_spte(sptep, shadow_trap_nonpresent_pte);
315 kvm_flush_remote_tlbs(vcpu->kvm); 321 kvm_flush_remote_tlbs(vcpu->kvm);
316 } 322 }
317 323
318 if (level == PT_DIRECTORY_LEVEL 324 if (level <= gw->level) {
319 && gw->level == PT_DIRECTORY_LEVEL) { 325 int delta = level - gw->level + 1;
320 direct = 1; 326 direct = 1;
321 if (!is_dirty_pte(gw->ptes[level - 1])) 327 if (!is_dirty_gpte(gw->ptes[level - delta]))
322 access &= ~ACC_WRITE_MASK; 328 access &= ~ACC_WRITE_MASK;
323 table_gfn = gpte_to_gfn(gw->ptes[level - 1]); 329 table_gfn = gpte_to_gfn(gw->ptes[level - delta]);
330 /* advance table_gfn when emulating 1gb pages with 4k */
331 if (delta == 0)
332 table_gfn += PT_INDEX(addr, level);
324 } else { 333 } else {
325 direct = 0; 334 direct = 0;
326 table_gfn = gw->table_gfn[level - 2]; 335 table_gfn = gw->table_gfn[level - 2];
@@ -369,11 +378,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
369 int user_fault = error_code & PFERR_USER_MASK; 378 int user_fault = error_code & PFERR_USER_MASK;
370 int fetch_fault = error_code & PFERR_FETCH_MASK; 379 int fetch_fault = error_code & PFERR_FETCH_MASK;
371 struct guest_walker walker; 380 struct guest_walker walker;
372 u64 *shadow_pte; 381 u64 *sptep;
373 int write_pt = 0; 382 int write_pt = 0;
374 int r; 383 int r;
375 pfn_t pfn; 384 pfn_t pfn;
376 int largepage = 0; 385 int level = PT_PAGE_TABLE_LEVEL;
377 unsigned long mmu_seq; 386 unsigned long mmu_seq;
378 387
379 pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code); 388 pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
@@ -399,14 +408,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
399 return 0; 408 return 0;
400 } 409 }
401 410
402 if (walker.level == PT_DIRECTORY_LEVEL) { 411 if (walker.level >= PT_DIRECTORY_LEVEL) {
403 gfn_t large_gfn; 412 level = min(walker.level, mapping_level(vcpu, walker.gfn));
404 large_gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE-1); 413 walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
405 if (is_largepage_backed(vcpu, large_gfn)) {
406 walker.gfn = large_gfn;
407 largepage = 1;
408 }
409 } 414 }
415
410 mmu_seq = vcpu->kvm->mmu_notifier_seq; 416 mmu_seq = vcpu->kvm->mmu_notifier_seq;
411 smp_rmb(); 417 smp_rmb();
412 pfn = gfn_to_pfn(vcpu->kvm, walker.gfn); 418 pfn = gfn_to_pfn(vcpu->kvm, walker.gfn);
@@ -422,11 +428,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
422 if (mmu_notifier_retry(vcpu, mmu_seq)) 428 if (mmu_notifier_retry(vcpu, mmu_seq))
423 goto out_unlock; 429 goto out_unlock;
424 kvm_mmu_free_some_pages(vcpu); 430 kvm_mmu_free_some_pages(vcpu);
425 shadow_pte = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault, 431 sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
426 largepage, &write_pt, pfn); 432 level, &write_pt, pfn);
427
428 pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__, 433 pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__,
429 shadow_pte, *shadow_pte, write_pt); 434 sptep, *sptep, write_pt);
430 435
431 if (!write_pt) 436 if (!write_pt)
432 vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ 437 vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
@@ -459,8 +464,9 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
459 sptep = iterator.sptep; 464 sptep = iterator.sptep;
460 465
461 /* FIXME: properly handle invlpg on large guest pages */ 466 /* FIXME: properly handle invlpg on large guest pages */
462 if (level == PT_PAGE_TABLE_LEVEL || 467 if (level == PT_PAGE_TABLE_LEVEL ||
463 ((level == PT_DIRECTORY_LEVEL) && is_large_pte(*sptep))) { 468 ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) ||
469 ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) {
464 struct kvm_mmu_page *sp = page_header(__pa(sptep)); 470 struct kvm_mmu_page *sp = page_header(__pa(sptep));
465 471
466 pte_gpa = (sp->gfn << PAGE_SHIFT); 472 pte_gpa = (sp->gfn << PAGE_SHIFT);
@@ -472,7 +478,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
472 --vcpu->kvm->stat.lpages; 478 --vcpu->kvm->stat.lpages;
473 need_flush = 1; 479 need_flush = 1;
474 } 480 }
475 set_shadow_pte(sptep, shadow_trap_nonpresent_pte); 481 __set_spte(sptep, shadow_trap_nonpresent_pte);
476 break; 482 break;
477 } 483 }
478 484
@@ -489,7 +495,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
489 if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte, 495 if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
490 sizeof(pt_element_t))) 496 sizeof(pt_element_t)))
491 return; 497 return;
492 if (is_present_pte(gpte) && (gpte & PT_ACCESSED_MASK)) { 498 if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) {
493 if (mmu_topup_memory_caches(vcpu)) 499 if (mmu_topup_memory_caches(vcpu))
494 return; 500 return;
495 kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte, 501 kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
@@ -536,7 +542,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
536 r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, pt, sizeof pt); 542 r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, pt, sizeof pt);
537 pte_gpa += ARRAY_SIZE(pt) * sizeof(pt_element_t); 543 pte_gpa += ARRAY_SIZE(pt) * sizeof(pt_element_t);
538 for (j = 0; j < ARRAY_SIZE(pt); ++j) 544 for (j = 0; j < ARRAY_SIZE(pt); ++j)
539 if (r || is_present_pte(pt[j])) 545 if (r || is_present_gpte(pt[j]))
540 sp->spt[i+j] = shadow_trap_nonpresent_pte; 546 sp->spt[i+j] = shadow_trap_nonpresent_pte;
541 else 547 else
542 sp->spt[i+j] = shadow_notrap_nonpresent_pte; 548 sp->spt[i+j] = shadow_notrap_nonpresent_pte;
@@ -574,23 +580,23 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
574 sizeof(pt_element_t))) 580 sizeof(pt_element_t)))
575 return -EINVAL; 581 return -EINVAL;
576 582
577 if (gpte_to_gfn(gpte) != gfn || !is_present_pte(gpte) || 583 if (gpte_to_gfn(gpte) != gfn || !is_present_gpte(gpte) ||
578 !(gpte & PT_ACCESSED_MASK)) { 584 !(gpte & PT_ACCESSED_MASK)) {
579 u64 nonpresent; 585 u64 nonpresent;
580 586
581 rmap_remove(vcpu->kvm, &sp->spt[i]); 587 rmap_remove(vcpu->kvm, &sp->spt[i]);
582 if (is_present_pte(gpte)) 588 if (is_present_gpte(gpte))
583 nonpresent = shadow_trap_nonpresent_pte; 589 nonpresent = shadow_trap_nonpresent_pte;
584 else 590 else
585 nonpresent = shadow_notrap_nonpresent_pte; 591 nonpresent = shadow_notrap_nonpresent_pte;
586 set_shadow_pte(&sp->spt[i], nonpresent); 592 __set_spte(&sp->spt[i], nonpresent);
587 continue; 593 continue;
588 } 594 }
589 595
590 nr_present++; 596 nr_present++;
591 pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); 597 pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
592 set_spte(vcpu, &sp->spt[i], pte_access, 0, 0, 598 set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
593 is_dirty_pte(gpte), 0, gfn, 599 is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn,
594 spte_to_pfn(sp->spt[i]), true, false); 600 spte_to_pfn(sp->spt[i]), true, false);
595 } 601 }
596 602
@@ -603,9 +609,10 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
603#undef PT_BASE_ADDR_MASK 609#undef PT_BASE_ADDR_MASK
604#undef PT_INDEX 610#undef PT_INDEX
605#undef PT_LEVEL_MASK 611#undef PT_LEVEL_MASK
606#undef PT_DIR_BASE_ADDR_MASK 612#undef PT_LVL_ADDR_MASK
613#undef PT_LVL_OFFSET_MASK
607#undef PT_LEVEL_BITS 614#undef PT_LEVEL_BITS
608#undef PT_MAX_FULL_LEVELS 615#undef PT_MAX_FULL_LEVELS
609#undef gpte_to_gfn 616#undef gpte_to_gfn
610#undef gpte_to_gfn_pde 617#undef gpte_to_gfn_lvl
611#undef CMPXCHG 618#undef CMPXCHG
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b1f658ad2f06..944cc9c04b3c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -15,7 +15,6 @@
15 */ 15 */
16#include <linux/kvm_host.h> 16#include <linux/kvm_host.h>
17 17
18#include "kvm_svm.h"
19#include "irq.h" 18#include "irq.h"
20#include "mmu.h" 19#include "mmu.h"
21#include "kvm_cache_regs.h" 20#include "kvm_cache_regs.h"
@@ -26,10 +25,12 @@
26#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
27#include <linux/highmem.h> 26#include <linux/highmem.h>
28#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/ftrace_event.h>
29 29
30#include <asm/desc.h> 30#include <asm/desc.h>
31 31
32#include <asm/virtext.h> 32#include <asm/virtext.h>
33#include "trace.h"
33 34
34#define __ex(x) __kvm_handle_fault_on_reboot(x) 35#define __ex(x) __kvm_handle_fault_on_reboot(x)
35 36
@@ -46,6 +47,10 @@ MODULE_LICENSE("GPL");
46#define SVM_FEATURE_LBRV (1 << 1) 47#define SVM_FEATURE_LBRV (1 << 1)
47#define SVM_FEATURE_SVML (1 << 2) 48#define SVM_FEATURE_SVML (1 << 2)
48 49
50#define NESTED_EXIT_HOST 0 /* Exit handled on host level */
51#define NESTED_EXIT_DONE 1 /* Exit caused nested vmexit */
52#define NESTED_EXIT_CONTINUE 2 /* Further checks needed */
53
49#define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) 54#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
50 55
51/* Turn on to get debugging output*/ 56/* Turn on to get debugging output*/
@@ -57,6 +62,58 @@ MODULE_LICENSE("GPL");
57#define nsvm_printk(fmt, args...) do {} while(0) 62#define nsvm_printk(fmt, args...) do {} while(0)
58#endif 63#endif
59 64
65static const u32 host_save_user_msrs[] = {
66#ifdef CONFIG_X86_64
67 MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
68 MSR_FS_BASE,
69#endif
70 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
71};
72
73#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
74
75struct kvm_vcpu;
76
77struct nested_state {
78 struct vmcb *hsave;
79 u64 hsave_msr;
80 u64 vmcb;
81
82 /* These are the merged vectors */
83 u32 *msrpm;
84
85 /* gpa pointers to the real vectors */
86 u64 vmcb_msrpm;
87
88 /* cache for intercepts of the guest */
89 u16 intercept_cr_read;
90 u16 intercept_cr_write;
91 u16 intercept_dr_read;
92 u16 intercept_dr_write;
93 u32 intercept_exceptions;
94 u64 intercept;
95
96};
97
98struct vcpu_svm {
99 struct kvm_vcpu vcpu;
100 struct vmcb *vmcb;
101 unsigned long vmcb_pa;
102 struct svm_cpu_data *svm_data;
103 uint64_t asid_generation;
104 uint64_t sysenter_esp;
105 uint64_t sysenter_eip;
106
107 u64 next_rip;
108
109 u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
110 u64 host_gs_base;
111
112 u32 *msrpm;
113
114 struct nested_state nested;
115};
116
60/* enable NPT for AMD64 and X86 with PAE */ 117/* enable NPT for AMD64 and X86 with PAE */
61#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) 118#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
62static bool npt_enabled = true; 119static bool npt_enabled = true;
@@ -67,15 +124,14 @@ static int npt = 1;
67 124
68module_param(npt, int, S_IRUGO); 125module_param(npt, int, S_IRUGO);
69 126
70static int nested = 0; 127static int nested = 1;
71module_param(nested, int, S_IRUGO); 128module_param(nested, int, S_IRUGO);
72 129
73static void svm_flush_tlb(struct kvm_vcpu *vcpu); 130static void svm_flush_tlb(struct kvm_vcpu *vcpu);
131static void svm_complete_interrupts(struct vcpu_svm *svm);
74 132
75static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override); 133static int nested_svm_exit_handled(struct vcpu_svm *svm);
76static int nested_svm_vmexit(struct vcpu_svm *svm); 134static int nested_svm_vmexit(struct vcpu_svm *svm);
77static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
78 void *arg2, void *opaque);
79static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, 135static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
80 bool has_error_code, u32 error_code); 136 bool has_error_code, u32 error_code);
81 137
@@ -86,7 +142,22 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
86 142
87static inline bool is_nested(struct vcpu_svm *svm) 143static inline bool is_nested(struct vcpu_svm *svm)
88{ 144{
89 return svm->nested_vmcb; 145 return svm->nested.vmcb;
146}
147
148static inline void enable_gif(struct vcpu_svm *svm)
149{
150 svm->vcpu.arch.hflags |= HF_GIF_MASK;
151}
152
153static inline void disable_gif(struct vcpu_svm *svm)
154{
155 svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
156}
157
158static inline bool gif_set(struct vcpu_svm *svm)
159{
160 return !!(svm->vcpu.arch.hflags & HF_GIF_MASK);
90} 161}
91 162
92static unsigned long iopm_base; 163static unsigned long iopm_base;
@@ -147,19 +218,6 @@ static inline void invlpga(unsigned long addr, u32 asid)
147 asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid)); 218 asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid));
148} 219}
149 220
150static inline unsigned long kvm_read_cr2(void)
151{
152 unsigned long cr2;
153
154 asm volatile ("mov %%cr2, %0" : "=r" (cr2));
155 return cr2;
156}
157
158static inline void kvm_write_cr2(unsigned long val)
159{
160 asm volatile ("mov %0, %%cr2" :: "r" (val));
161}
162
163static inline void force_new_asid(struct kvm_vcpu *vcpu) 221static inline void force_new_asid(struct kvm_vcpu *vcpu)
164{ 222{
165 to_svm(vcpu)->asid_generation--; 223 to_svm(vcpu)->asid_generation--;
@@ -263,7 +321,7 @@ static void svm_hardware_enable(void *garbage)
263 321
264 struct svm_cpu_data *svm_data; 322 struct svm_cpu_data *svm_data;
265 uint64_t efer; 323 uint64_t efer;
266 struct desc_ptr gdt_descr; 324 struct descriptor_table gdt_descr;
267 struct desc_struct *gdt; 325 struct desc_struct *gdt;
268 int me = raw_smp_processor_id(); 326 int me = raw_smp_processor_id();
269 327
@@ -283,8 +341,8 @@ static void svm_hardware_enable(void *garbage)
283 svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; 341 svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
284 svm_data->next_asid = svm_data->max_asid + 1; 342 svm_data->next_asid = svm_data->max_asid + 1;
285 343
286 asm volatile ("sgdt %0" : "=m"(gdt_descr)); 344 kvm_get_gdt(&gdt_descr);
287 gdt = (struct desc_struct *)gdt_descr.address; 345 gdt = (struct desc_struct *)gdt_descr.base;
288 svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); 346 svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
289 347
290 rdmsrl(MSR_EFER, efer); 348 rdmsrl(MSR_EFER, efer);
@@ -367,8 +425,6 @@ static void svm_vcpu_init_msrpm(u32 *msrpm)
367#endif 425#endif
368 set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); 426 set_msr_interception(msrpm, MSR_K6_STAR, 1, 1);
369 set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); 427 set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1);
370 set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1);
371 set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1);
372} 428}
373 429
374static void svm_enable_lbrv(struct vcpu_svm *svm) 430static void svm_enable_lbrv(struct vcpu_svm *svm)
@@ -595,8 +651,10 @@ static void init_vmcb(struct vcpu_svm *svm)
595 } 651 }
596 force_new_asid(&svm->vcpu); 652 force_new_asid(&svm->vcpu);
597 653
598 svm->nested_vmcb = 0; 654 svm->nested.vmcb = 0;
599 svm->vcpu.arch.hflags = HF_GIF_MASK; 655 svm->vcpu.arch.hflags = 0;
656
657 enable_gif(svm);
600} 658}
601 659
602static int svm_vcpu_reset(struct kvm_vcpu *vcpu) 660static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
@@ -605,7 +663,7 @@ static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
605 663
606 init_vmcb(svm); 664 init_vmcb(svm);
607 665
608 if (vcpu->vcpu_id != 0) { 666 if (!kvm_vcpu_is_bsp(vcpu)) {
609 kvm_rip_write(vcpu, 0); 667 kvm_rip_write(vcpu, 0);
610 svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12; 668 svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12;
611 svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8; 669 svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8;
@@ -656,9 +714,9 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
656 hsave_page = alloc_page(GFP_KERNEL); 714 hsave_page = alloc_page(GFP_KERNEL);
657 if (!hsave_page) 715 if (!hsave_page)
658 goto uninit; 716 goto uninit;
659 svm->hsave = page_address(hsave_page); 717 svm->nested.hsave = page_address(hsave_page);
660 718
661 svm->nested_msrpm = page_address(nested_msrpm_pages); 719 svm->nested.msrpm = page_address(nested_msrpm_pages);
662 720
663 svm->vmcb = page_address(page); 721 svm->vmcb = page_address(page);
664 clear_page(svm->vmcb); 722 clear_page(svm->vmcb);
@@ -669,7 +727,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
669 fx_init(&svm->vcpu); 727 fx_init(&svm->vcpu);
670 svm->vcpu.fpu_active = 1; 728 svm->vcpu.fpu_active = 1;
671 svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; 729 svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
672 if (svm->vcpu.vcpu_id == 0) 730 if (kvm_vcpu_is_bsp(&svm->vcpu))
673 svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; 731 svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
674 732
675 return &svm->vcpu; 733 return &svm->vcpu;
@@ -688,8 +746,8 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
688 746
689 __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT)); 747 __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
690 __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER); 748 __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
691 __free_page(virt_to_page(svm->hsave)); 749 __free_page(virt_to_page(svm->nested.hsave));
692 __free_pages(virt_to_page(svm->nested_msrpm), MSRPM_ALLOC_ORDER); 750 __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
693 kvm_vcpu_uninit(vcpu); 751 kvm_vcpu_uninit(vcpu);
694 kmem_cache_free(kvm_vcpu_cache, svm); 752 kmem_cache_free(kvm_vcpu_cache, svm);
695} 753}
@@ -740,6 +798,18 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
740 to_svm(vcpu)->vmcb->save.rflags = rflags; 798 to_svm(vcpu)->vmcb->save.rflags = rflags;
741} 799}
742 800
801static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
802{
803 switch (reg) {
804 case VCPU_EXREG_PDPTR:
805 BUG_ON(!npt_enabled);
806 load_pdptrs(vcpu, vcpu->arch.cr3);
807 break;
808 default:
809 BUG();
810 }
811}
812
743static void svm_set_vintr(struct vcpu_svm *svm) 813static void svm_set_vintr(struct vcpu_svm *svm)
744{ 814{
745 svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR; 815 svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR;
@@ -1061,7 +1131,6 @@ static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
1061 val = 0; 1131 val = 0;
1062 } 1132 }
1063 1133
1064 KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
1065 return val; 1134 return val;
1066} 1135}
1067 1136
@@ -1070,8 +1139,6 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
1070{ 1139{
1071 struct vcpu_svm *svm = to_svm(vcpu); 1140 struct vcpu_svm *svm = to_svm(vcpu);
1072 1141
1073 KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)value, handler);
1074
1075 *exception = 0; 1142 *exception = 0;
1076 1143
1077 switch (dr) { 1144 switch (dr) {
@@ -1119,25 +1186,9 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1119 fault_address = svm->vmcb->control.exit_info_2; 1186 fault_address = svm->vmcb->control.exit_info_2;
1120 error_code = svm->vmcb->control.exit_info_1; 1187 error_code = svm->vmcb->control.exit_info_1;
1121 1188
1122 if (!npt_enabled) 1189 trace_kvm_page_fault(fault_address, error_code);
1123 KVMTRACE_3D(PAGE_FAULT, &svm->vcpu, error_code, 1190 if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu))
1124 (u32)fault_address, (u32)(fault_address >> 32), 1191 kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
1125 handler);
1126 else
1127 KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code,
1128 (u32)fault_address, (u32)(fault_address >> 32),
1129 handler);
1130 /*
1131 * FIXME: Tis shouldn't be necessary here, but there is a flush
1132 * missing in the MMU code. Until we find this bug, flush the
1133 * complete TLB here on an NPF
1134 */
1135 if (npt_enabled)
1136 svm_flush_tlb(&svm->vcpu);
1137 else {
1138 if (kvm_event_needs_reinjection(&svm->vcpu))
1139 kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
1140 }
1141 return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); 1192 return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
1142} 1193}
1143 1194
@@ -1253,14 +1304,12 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1253 1304
1254static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1305static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1255{ 1306{
1256 KVMTRACE_0D(NMI, &svm->vcpu, handler);
1257 return 1; 1307 return 1;
1258} 1308}
1259 1309
1260static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1310static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1261{ 1311{
1262 ++svm->vcpu.stat.irq_exits; 1312 ++svm->vcpu.stat.irq_exits;
1263 KVMTRACE_0D(INTR, &svm->vcpu, handler);
1264 return 1; 1313 return 1;
1265} 1314}
1266 1315
@@ -1303,44 +1352,39 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm)
1303static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, 1352static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
1304 bool has_error_code, u32 error_code) 1353 bool has_error_code, u32 error_code)
1305{ 1354{
1306 if (is_nested(svm)) { 1355 if (!is_nested(svm))
1307 svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr; 1356 return 0;
1308 svm->vmcb->control.exit_code_hi = 0;
1309 svm->vmcb->control.exit_info_1 = error_code;
1310 svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
1311 if (nested_svm_exit_handled(svm, false)) {
1312 nsvm_printk("VMexit -> EXCP 0x%x\n", nr);
1313
1314 nested_svm_vmexit(svm);
1315 return 1;
1316 }
1317 }
1318 1357
1319 return 0; 1358 svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
1359 svm->vmcb->control.exit_code_hi = 0;
1360 svm->vmcb->control.exit_info_1 = error_code;
1361 svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
1362
1363 return nested_svm_exit_handled(svm);
1320} 1364}
1321 1365
1322static inline int nested_svm_intr(struct vcpu_svm *svm) 1366static inline int nested_svm_intr(struct vcpu_svm *svm)
1323{ 1367{
1324 if (is_nested(svm)) { 1368 if (!is_nested(svm))
1325 if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) 1369 return 0;
1326 return 0;
1327 1370
1328 if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) 1371 if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
1329 return 0; 1372 return 0;
1330 1373
1331 svm->vmcb->control.exit_code = SVM_EXIT_INTR; 1374 if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
1375 return 0;
1332 1376
1333 if (nested_svm_exit_handled(svm, false)) { 1377 svm->vmcb->control.exit_code = SVM_EXIT_INTR;
1334 nsvm_printk("VMexit -> INTR\n"); 1378
1335 nested_svm_vmexit(svm); 1379 if (nested_svm_exit_handled(svm)) {
1336 return 1; 1380 nsvm_printk("VMexit -> INTR\n");
1337 } 1381 return 1;
1338 } 1382 }
1339 1383
1340 return 0; 1384 return 0;
1341} 1385}
1342 1386
1343static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa) 1387static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx)
1344{ 1388{
1345 struct page *page; 1389 struct page *page;
1346 1390
@@ -1348,236 +1392,246 @@ static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa)
1348 page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); 1392 page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT);
1349 up_read(&current->mm->mmap_sem); 1393 up_read(&current->mm->mmap_sem);
1350 1394
1351 if (is_error_page(page)) { 1395 if (is_error_page(page))
1352 printk(KERN_INFO "%s: could not find page at 0x%llx\n", 1396 goto error;
1353 __func__, gpa); 1397
1354 kvm_release_page_clean(page); 1398 return kmap_atomic(page, idx);
1355 kvm_inject_gp(&svm->vcpu, 0); 1399
1356 return NULL; 1400error:
1357 } 1401 kvm_release_page_clean(page);
1358 return page; 1402 kvm_inject_gp(&svm->vcpu, 0);
1403
1404 return NULL;
1359} 1405}
1360 1406
1361static int nested_svm_do(struct vcpu_svm *svm, 1407static void nested_svm_unmap(void *addr, enum km_type idx)
1362 u64 arg1_gpa, u64 arg2_gpa, void *opaque,
1363 int (*handler)(struct vcpu_svm *svm,
1364 void *arg1,
1365 void *arg2,
1366 void *opaque))
1367{ 1408{
1368 struct page *arg1_page; 1409 struct page *page;
1369 struct page *arg2_page = NULL;
1370 void *arg1;
1371 void *arg2 = NULL;
1372 int retval;
1373 1410
1374 arg1_page = nested_svm_get_page(svm, arg1_gpa); 1411 if (!addr)
1375 if(arg1_page == NULL) 1412 return;
1376 return 1;
1377 1413
1378 if (arg2_gpa) { 1414 page = kmap_atomic_to_page(addr);
1379 arg2_page = nested_svm_get_page(svm, arg2_gpa); 1415
1380 if(arg2_page == NULL) { 1416 kunmap_atomic(addr, idx);
1381 kvm_release_page_clean(arg1_page); 1417 kvm_release_page_dirty(page);
1382 return 1; 1418}
1383 } 1419
1384 } 1420static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
1421{
1422 u32 param = svm->vmcb->control.exit_info_1 & 1;
1423 u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
1424 bool ret = false;
1425 u32 t0, t1;
1426 u8 *msrpm;
1385 1427
1386 arg1 = kmap_atomic(arg1_page, KM_USER0); 1428 if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT)))
1387 if (arg2_gpa) 1429 return false;
1388 arg2 = kmap_atomic(arg2_page, KM_USER1);
1389 1430
1390 retval = handler(svm, arg1, arg2, opaque); 1431 msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
1432
1433 if (!msrpm)
1434 goto out;
1435
1436 switch (msr) {
1437 case 0 ... 0x1fff:
1438 t0 = (msr * 2) % 8;
1439 t1 = msr / 8;
1440 break;
1441 case 0xc0000000 ... 0xc0001fff:
1442 t0 = (8192 + msr - 0xc0000000) * 2;
1443 t1 = (t0 / 8);
1444 t0 %= 8;
1445 break;
1446 case 0xc0010000 ... 0xc0011fff:
1447 t0 = (16384 + msr - 0xc0010000) * 2;
1448 t1 = (t0 / 8);
1449 t0 %= 8;
1450 break;
1451 default:
1452 ret = true;
1453 goto out;
1454 }
1391 1455
1392 kunmap_atomic(arg1, KM_USER0); 1456 ret = msrpm[t1] & ((1 << param) << t0);
1393 if (arg2_gpa)
1394 kunmap_atomic(arg2, KM_USER1);
1395 1457
1396 kvm_release_page_dirty(arg1_page); 1458out:
1397 if (arg2_gpa) 1459 nested_svm_unmap(msrpm, KM_USER0);
1398 kvm_release_page_dirty(arg2_page);
1399 1460
1400 return retval; 1461 return ret;
1401} 1462}
1402 1463
1403static int nested_svm_exit_handled_real(struct vcpu_svm *svm, 1464static int nested_svm_exit_special(struct vcpu_svm *svm)
1404 void *arg1,
1405 void *arg2,
1406 void *opaque)
1407{ 1465{
1408 struct vmcb *nested_vmcb = (struct vmcb *)arg1;
1409 bool kvm_overrides = *(bool *)opaque;
1410 u32 exit_code = svm->vmcb->control.exit_code; 1466 u32 exit_code = svm->vmcb->control.exit_code;
1411 1467
1412 if (kvm_overrides) { 1468 switch (exit_code) {
1413 switch (exit_code) { 1469 case SVM_EXIT_INTR:
1414 case SVM_EXIT_INTR: 1470 case SVM_EXIT_NMI:
1415 case SVM_EXIT_NMI: 1471 return NESTED_EXIT_HOST;
1416 return 0;
1417 /* For now we are always handling NPFs when using them */ 1472 /* For now we are always handling NPFs when using them */
1418 case SVM_EXIT_NPF: 1473 case SVM_EXIT_NPF:
1419 if (npt_enabled) 1474 if (npt_enabled)
1420 return 0; 1475 return NESTED_EXIT_HOST;
1421 break; 1476 break;
1422 /* When we're shadowing, trap PFs */ 1477 /* When we're shadowing, trap PFs */
1423 case SVM_EXIT_EXCP_BASE + PF_VECTOR: 1478 case SVM_EXIT_EXCP_BASE + PF_VECTOR:
1424 if (!npt_enabled) 1479 if (!npt_enabled)
1425 return 0; 1480 return NESTED_EXIT_HOST;
1426 break; 1481 break;
1427 default: 1482 default:
1428 break; 1483 break;
1429 }
1430 } 1484 }
1431 1485
1486 return NESTED_EXIT_CONTINUE;
1487}
1488
1489/*
1490 * If this function returns true, this #vmexit was already handled
1491 */
1492static int nested_svm_exit_handled(struct vcpu_svm *svm)
1493{
1494 u32 exit_code = svm->vmcb->control.exit_code;
1495 int vmexit = NESTED_EXIT_HOST;
1496
1432 switch (exit_code) { 1497 switch (exit_code) {
1498 case SVM_EXIT_MSR:
1499 vmexit = nested_svm_exit_handled_msr(svm);
1500 break;
1433 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { 1501 case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: {
1434 u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); 1502 u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0);
1435 if (nested_vmcb->control.intercept_cr_read & cr_bits) 1503 if (svm->nested.intercept_cr_read & cr_bits)
1436 return 1; 1504 vmexit = NESTED_EXIT_DONE;
1437 break; 1505 break;
1438 } 1506 }
1439 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: { 1507 case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: {
1440 u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0); 1508 u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0);
1441 if (nested_vmcb->control.intercept_cr_write & cr_bits) 1509 if (svm->nested.intercept_cr_write & cr_bits)
1442 return 1; 1510 vmexit = NESTED_EXIT_DONE;
1443 break; 1511 break;
1444 } 1512 }
1445 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: { 1513 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: {
1446 u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0); 1514 u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0);
1447 if (nested_vmcb->control.intercept_dr_read & dr_bits) 1515 if (svm->nested.intercept_dr_read & dr_bits)
1448 return 1; 1516 vmexit = NESTED_EXIT_DONE;
1449 break; 1517 break;
1450 } 1518 }
1451 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: { 1519 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
1452 u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0); 1520 u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
1453 if (nested_vmcb->control.intercept_dr_write & dr_bits) 1521 if (svm->nested.intercept_dr_write & dr_bits)
1454 return 1; 1522 vmexit = NESTED_EXIT_DONE;
1455 break; 1523 break;
1456 } 1524 }
1457 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: { 1525 case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: {
1458 u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); 1526 u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE);
1459 if (nested_vmcb->control.intercept_exceptions & excp_bits) 1527 if (svm->nested.intercept_exceptions & excp_bits)
1460 return 1; 1528 vmexit = NESTED_EXIT_DONE;
1461 break; 1529 break;
1462 } 1530 }
1463 default: { 1531 default: {
1464 u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR); 1532 u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR);
1465 nsvm_printk("exit code: 0x%x\n", exit_code); 1533 nsvm_printk("exit code: 0x%x\n", exit_code);
1466 if (nested_vmcb->control.intercept & exit_bits) 1534 if (svm->nested.intercept & exit_bits)
1467 return 1; 1535 vmexit = NESTED_EXIT_DONE;
1468 } 1536 }
1469 } 1537 }
1470 1538
1471 return 0; 1539 if (vmexit == NESTED_EXIT_DONE) {
1472} 1540 nsvm_printk("#VMEXIT reason=%04x\n", exit_code);
1473 1541 nested_svm_vmexit(svm);
1474static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
1475 void *arg1, void *arg2,
1476 void *opaque)
1477{
1478 struct vmcb *nested_vmcb = (struct vmcb *)arg1;
1479 u8 *msrpm = (u8 *)arg2;
1480 u32 t0, t1;
1481 u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
1482 u32 param = svm->vmcb->control.exit_info_1 & 1;
1483
1484 if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT)))
1485 return 0;
1486
1487 switch(msr) {
1488 case 0 ... 0x1fff:
1489 t0 = (msr * 2) % 8;
1490 t1 = msr / 8;
1491 break;
1492 case 0xc0000000 ... 0xc0001fff:
1493 t0 = (8192 + msr - 0xc0000000) * 2;
1494 t1 = (t0 / 8);
1495 t0 %= 8;
1496 break;
1497 case 0xc0010000 ... 0xc0011fff:
1498 t0 = (16384 + msr - 0xc0010000) * 2;
1499 t1 = (t0 / 8);
1500 t0 %= 8;
1501 break;
1502 default:
1503 return 1;
1504 break;
1505 } 1542 }
1506 if (msrpm[t1] & ((1 << param) << t0))
1507 return 1;
1508 1543
1509 return 0; 1544 return vmexit;
1545}
1546
1547static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb)
1548{
1549 struct vmcb_control_area *dst = &dst_vmcb->control;
1550 struct vmcb_control_area *from = &from_vmcb->control;
1551
1552 dst->intercept_cr_read = from->intercept_cr_read;
1553 dst->intercept_cr_write = from->intercept_cr_write;
1554 dst->intercept_dr_read = from->intercept_dr_read;
1555 dst->intercept_dr_write = from->intercept_dr_write;
1556 dst->intercept_exceptions = from->intercept_exceptions;
1557 dst->intercept = from->intercept;
1558 dst->iopm_base_pa = from->iopm_base_pa;
1559 dst->msrpm_base_pa = from->msrpm_base_pa;
1560 dst->tsc_offset = from->tsc_offset;
1561 dst->asid = from->asid;
1562 dst->tlb_ctl = from->tlb_ctl;
1563 dst->int_ctl = from->int_ctl;
1564 dst->int_vector = from->int_vector;
1565 dst->int_state = from->int_state;
1566 dst->exit_code = from->exit_code;
1567 dst->exit_code_hi = from->exit_code_hi;
1568 dst->exit_info_1 = from->exit_info_1;
1569 dst->exit_info_2 = from->exit_info_2;
1570 dst->exit_int_info = from->exit_int_info;
1571 dst->exit_int_info_err = from->exit_int_info_err;
1572 dst->nested_ctl = from->nested_ctl;
1573 dst->event_inj = from->event_inj;
1574 dst->event_inj_err = from->event_inj_err;
1575 dst->nested_cr3 = from->nested_cr3;
1576 dst->lbr_ctl = from->lbr_ctl;
1510} 1577}
1511 1578
1512static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override) 1579static int nested_svm_vmexit(struct vcpu_svm *svm)
1513{ 1580{
1514 bool k = kvm_override; 1581 struct vmcb *nested_vmcb;
1515 1582 struct vmcb *hsave = svm->nested.hsave;
1516 switch (svm->vmcb->control.exit_code) { 1583 struct vmcb *vmcb = svm->vmcb;
1517 case SVM_EXIT_MSR:
1518 return nested_svm_do(svm, svm->nested_vmcb,
1519 svm->nested_vmcb_msrpm, NULL,
1520 nested_svm_exit_handled_msr);
1521 default: break;
1522 }
1523 1584
1524 return nested_svm_do(svm, svm->nested_vmcb, 0, &k, 1585 nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0);
1525 nested_svm_exit_handled_real); 1586 if (!nested_vmcb)
1526} 1587 return 1;
1527
1528static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
1529 void *arg2, void *opaque)
1530{
1531 struct vmcb *nested_vmcb = (struct vmcb *)arg1;
1532 struct vmcb *hsave = svm->hsave;
1533 u64 nested_save[] = { nested_vmcb->save.cr0,
1534 nested_vmcb->save.cr3,
1535 nested_vmcb->save.cr4,
1536 nested_vmcb->save.efer,
1537 nested_vmcb->control.intercept_cr_read,
1538 nested_vmcb->control.intercept_cr_write,
1539 nested_vmcb->control.intercept_dr_read,
1540 nested_vmcb->control.intercept_dr_write,
1541 nested_vmcb->control.intercept_exceptions,
1542 nested_vmcb->control.intercept,
1543 nested_vmcb->control.msrpm_base_pa,
1544 nested_vmcb->control.iopm_base_pa,
1545 nested_vmcb->control.tsc_offset };
1546 1588
1547 /* Give the current vmcb to the guest */ 1589 /* Give the current vmcb to the guest */
1548 memcpy(nested_vmcb, svm->vmcb, sizeof(struct vmcb)); 1590 disable_gif(svm);
1549 nested_vmcb->save.cr0 = nested_save[0]; 1591
1550 if (!npt_enabled) 1592 nested_vmcb->save.es = vmcb->save.es;
1551 nested_vmcb->save.cr3 = nested_save[1]; 1593 nested_vmcb->save.cs = vmcb->save.cs;
1552 nested_vmcb->save.cr4 = nested_save[2]; 1594 nested_vmcb->save.ss = vmcb->save.ss;
1553 nested_vmcb->save.efer = nested_save[3]; 1595 nested_vmcb->save.ds = vmcb->save.ds;
1554 nested_vmcb->control.intercept_cr_read = nested_save[4]; 1596 nested_vmcb->save.gdtr = vmcb->save.gdtr;
1555 nested_vmcb->control.intercept_cr_write = nested_save[5]; 1597 nested_vmcb->save.idtr = vmcb->save.idtr;
1556 nested_vmcb->control.intercept_dr_read = nested_save[6]; 1598 if (npt_enabled)
1557 nested_vmcb->control.intercept_dr_write = nested_save[7]; 1599 nested_vmcb->save.cr3 = vmcb->save.cr3;
1558 nested_vmcb->control.intercept_exceptions = nested_save[8]; 1600 nested_vmcb->save.cr2 = vmcb->save.cr2;
1559 nested_vmcb->control.intercept = nested_save[9]; 1601 nested_vmcb->save.rflags = vmcb->save.rflags;
1560 nested_vmcb->control.msrpm_base_pa = nested_save[10]; 1602 nested_vmcb->save.rip = vmcb->save.rip;
1561 nested_vmcb->control.iopm_base_pa = nested_save[11]; 1603 nested_vmcb->save.rsp = vmcb->save.rsp;
1562 nested_vmcb->control.tsc_offset = nested_save[12]; 1604 nested_vmcb->save.rax = vmcb->save.rax;
1605 nested_vmcb->save.dr7 = vmcb->save.dr7;
1606 nested_vmcb->save.dr6 = vmcb->save.dr6;
1607 nested_vmcb->save.cpl = vmcb->save.cpl;
1608
1609 nested_vmcb->control.int_ctl = vmcb->control.int_ctl;
1610 nested_vmcb->control.int_vector = vmcb->control.int_vector;
1611 nested_vmcb->control.int_state = vmcb->control.int_state;
1612 nested_vmcb->control.exit_code = vmcb->control.exit_code;
1613 nested_vmcb->control.exit_code_hi = vmcb->control.exit_code_hi;
1614 nested_vmcb->control.exit_info_1 = vmcb->control.exit_info_1;
1615 nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2;
1616 nested_vmcb->control.exit_int_info = vmcb->control.exit_int_info;
1617 nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err;
1618 nested_vmcb->control.tlb_ctl = 0;
1619 nested_vmcb->control.event_inj = 0;
1620 nested_vmcb->control.event_inj_err = 0;
1563 1621
1564 /* We always set V_INTR_MASKING and remember the old value in hflags */ 1622 /* We always set V_INTR_MASKING and remember the old value in hflags */
1565 if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) 1623 if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
1566 nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; 1624 nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
1567 1625
1568 if ((nested_vmcb->control.int_ctl & V_IRQ_MASK) &&
1569 (nested_vmcb->control.int_vector)) {
1570 nsvm_printk("WARNING: IRQ 0x%x still enabled on #VMEXIT\n",
1571 nested_vmcb->control.int_vector);
1572 }
1573
1574 /* Restore the original control entries */ 1626 /* Restore the original control entries */
1575 svm->vmcb->control = hsave->control; 1627 copy_vmcb_control_area(vmcb, hsave);
1576 1628
1577 /* Kill any pending exceptions */ 1629 /* Kill any pending exceptions */
1578 if (svm->vcpu.arch.exception.pending == true) 1630 if (svm->vcpu.arch.exception.pending == true)
1579 nsvm_printk("WARNING: Pending Exception\n"); 1631 nsvm_printk("WARNING: Pending Exception\n");
1580 svm->vcpu.arch.exception.pending = false; 1632
1633 kvm_clear_exception_queue(&svm->vcpu);
1634 kvm_clear_interrupt_queue(&svm->vcpu);
1581 1635
1582 /* Restore selected save entries */ 1636 /* Restore selected save entries */
1583 svm->vmcb->save.es = hsave->save.es; 1637 svm->vmcb->save.es = hsave->save.es;
@@ -1603,19 +1657,10 @@ static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
1603 svm->vmcb->save.cpl = 0; 1657 svm->vmcb->save.cpl = 0;
1604 svm->vmcb->control.exit_int_info = 0; 1658 svm->vmcb->control.exit_int_info = 0;
1605 1659
1606 svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
1607 /* Exit nested SVM mode */ 1660 /* Exit nested SVM mode */
1608 svm->nested_vmcb = 0; 1661 svm->nested.vmcb = 0;
1609 1662
1610 return 0; 1663 nested_svm_unmap(nested_vmcb, KM_USER0);
1611}
1612
1613static int nested_svm_vmexit(struct vcpu_svm *svm)
1614{
1615 nsvm_printk("VMexit\n");
1616 if (nested_svm_do(svm, svm->nested_vmcb, 0,
1617 NULL, nested_svm_vmexit_real))
1618 return 1;
1619 1664
1620 kvm_mmu_reset_context(&svm->vcpu); 1665 kvm_mmu_reset_context(&svm->vcpu);
1621 kvm_mmu_load(&svm->vcpu); 1666 kvm_mmu_load(&svm->vcpu);
@@ -1623,38 +1668,63 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
1623 return 0; 1668 return 0;
1624} 1669}
1625 1670
1626static int nested_svm_vmrun_msrpm(struct vcpu_svm *svm, void *arg1, 1671static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
1627 void *arg2, void *opaque)
1628{ 1672{
1673 u32 *nested_msrpm;
1629 int i; 1674 int i;
1630 u32 *nested_msrpm = (u32*)arg1; 1675
1676 nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
1677 if (!nested_msrpm)
1678 return false;
1679
1631 for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) 1680 for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
1632 svm->nested_msrpm[i] = svm->msrpm[i] | nested_msrpm[i]; 1681 svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
1633 svm->vmcb->control.msrpm_base_pa = __pa(svm->nested_msrpm);
1634 1682
1635 return 0; 1683 svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
1684
1685 nested_svm_unmap(nested_msrpm, KM_USER0);
1686
1687 return true;
1636} 1688}
1637 1689
1638static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1, 1690static bool nested_svm_vmrun(struct vcpu_svm *svm)
1639 void *arg2, void *opaque)
1640{ 1691{
1641 struct vmcb *nested_vmcb = (struct vmcb *)arg1; 1692 struct vmcb *nested_vmcb;
1642 struct vmcb *hsave = svm->hsave; 1693 struct vmcb *hsave = svm->nested.hsave;
1694 struct vmcb *vmcb = svm->vmcb;
1695
1696 nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
1697 if (!nested_vmcb)
1698 return false;
1643 1699
1644 /* nested_vmcb is our indicator if nested SVM is activated */ 1700 /* nested_vmcb is our indicator if nested SVM is activated */
1645 svm->nested_vmcb = svm->vmcb->save.rax; 1701 svm->nested.vmcb = svm->vmcb->save.rax;
1646 1702
1647 /* Clear internal status */ 1703 /* Clear internal status */
1648 svm->vcpu.arch.exception.pending = false; 1704 kvm_clear_exception_queue(&svm->vcpu);
1705 kvm_clear_interrupt_queue(&svm->vcpu);
1649 1706
1650 /* Save the old vmcb, so we don't need to pick what we save, but 1707 /* Save the old vmcb, so we don't need to pick what we save, but
1651 can restore everything when a VMEXIT occurs */ 1708 can restore everything when a VMEXIT occurs */
1652 memcpy(hsave, svm->vmcb, sizeof(struct vmcb)); 1709 hsave->save.es = vmcb->save.es;
1653 /* We need to remember the original CR3 in the SPT case */ 1710 hsave->save.cs = vmcb->save.cs;
1654 if (!npt_enabled) 1711 hsave->save.ss = vmcb->save.ss;
1655 hsave->save.cr3 = svm->vcpu.arch.cr3; 1712 hsave->save.ds = vmcb->save.ds;
1656 hsave->save.cr4 = svm->vcpu.arch.cr4; 1713 hsave->save.gdtr = vmcb->save.gdtr;
1657 hsave->save.rip = svm->next_rip; 1714 hsave->save.idtr = vmcb->save.idtr;
1715 hsave->save.efer = svm->vcpu.arch.shadow_efer;
1716 hsave->save.cr0 = svm->vcpu.arch.cr0;
1717 hsave->save.cr4 = svm->vcpu.arch.cr4;
1718 hsave->save.rflags = vmcb->save.rflags;
1719 hsave->save.rip = svm->next_rip;
1720 hsave->save.rsp = vmcb->save.rsp;
1721 hsave->save.rax = vmcb->save.rax;
1722 if (npt_enabled)
1723 hsave->save.cr3 = vmcb->save.cr3;
1724 else
1725 hsave->save.cr3 = svm->vcpu.arch.cr3;
1726
1727 copy_vmcb_control_area(hsave, vmcb);
1658 1728
1659 if (svm->vmcb->save.rflags & X86_EFLAGS_IF) 1729 if (svm->vmcb->save.rflags & X86_EFLAGS_IF)
1660 svm->vcpu.arch.hflags |= HF_HIF_MASK; 1730 svm->vcpu.arch.hflags |= HF_HIF_MASK;
@@ -1679,7 +1749,7 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
1679 kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); 1749 kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
1680 kvm_mmu_reset_context(&svm->vcpu); 1750 kvm_mmu_reset_context(&svm->vcpu);
1681 } 1751 }
1682 svm->vmcb->save.cr2 = nested_vmcb->save.cr2; 1752 svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2;
1683 kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); 1753 kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax);
1684 kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); 1754 kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp);
1685 kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip); 1755 kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip);
@@ -1706,7 +1776,15 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
1706 1776
1707 svm->vmcb->control.intercept |= nested_vmcb->control.intercept; 1777 svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
1708 1778
1709 svm->nested_vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; 1779 svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
1780
1781 /* cache intercepts */
1782 svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read;
1783 svm->nested.intercept_cr_write = nested_vmcb->control.intercept_cr_write;
1784 svm->nested.intercept_dr_read = nested_vmcb->control.intercept_dr_read;
1785 svm->nested.intercept_dr_write = nested_vmcb->control.intercept_dr_write;
1786 svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions;
1787 svm->nested.intercept = nested_vmcb->control.intercept;
1710 1788
1711 force_new_asid(&svm->vcpu); 1789 force_new_asid(&svm->vcpu);
1712 svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info; 1790 svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info;
@@ -1734,12 +1812,14 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
1734 svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; 1812 svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
1735 svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; 1813 svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
1736 1814
1737 svm->vcpu.arch.hflags |= HF_GIF_MASK; 1815 nested_svm_unmap(nested_vmcb, KM_USER0);
1738 1816
1739 return 0; 1817 enable_gif(svm);
1818
1819 return true;
1740} 1820}
1741 1821
1742static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) 1822static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
1743{ 1823{
1744 to_vmcb->save.fs = from_vmcb->save.fs; 1824 to_vmcb->save.fs = from_vmcb->save.fs;
1745 to_vmcb->save.gs = from_vmcb->save.gs; 1825 to_vmcb->save.gs = from_vmcb->save.gs;
@@ -1753,44 +1833,44 @@ static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
1753 to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs; 1833 to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs;
1754 to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp; 1834 to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp;
1755 to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip; 1835 to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip;
1756
1757 return 1;
1758}
1759
1760static int nested_svm_vmload(struct vcpu_svm *svm, void *nested_vmcb,
1761 void *arg2, void *opaque)
1762{
1763 return nested_svm_vmloadsave((struct vmcb *)nested_vmcb, svm->vmcb);
1764}
1765
1766static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
1767 void *arg2, void *opaque)
1768{
1769 return nested_svm_vmloadsave(svm->vmcb, (struct vmcb *)nested_vmcb);
1770} 1836}
1771 1837
1772static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1838static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1773{ 1839{
1840 struct vmcb *nested_vmcb;
1841
1774 if (nested_svm_check_permissions(svm)) 1842 if (nested_svm_check_permissions(svm))
1775 return 1; 1843 return 1;
1776 1844
1777 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; 1845 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
1778 skip_emulated_instruction(&svm->vcpu); 1846 skip_emulated_instruction(&svm->vcpu);
1779 1847
1780 nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmload); 1848 nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
1849 if (!nested_vmcb)
1850 return 1;
1851
1852 nested_svm_vmloadsave(nested_vmcb, svm->vmcb);
1853 nested_svm_unmap(nested_vmcb, KM_USER0);
1781 1854
1782 return 1; 1855 return 1;
1783} 1856}
1784 1857
1785static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1858static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1786{ 1859{
1860 struct vmcb *nested_vmcb;
1861
1787 if (nested_svm_check_permissions(svm)) 1862 if (nested_svm_check_permissions(svm))
1788 return 1; 1863 return 1;
1789 1864
1790 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; 1865 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
1791 skip_emulated_instruction(&svm->vcpu); 1866 skip_emulated_instruction(&svm->vcpu);
1792 1867
1793 nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmsave); 1868 nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
1869 if (!nested_vmcb)
1870 return 1;
1871
1872 nested_svm_vmloadsave(svm->vmcb, nested_vmcb);
1873 nested_svm_unmap(nested_vmcb, KM_USER0);
1794 1874
1795 return 1; 1875 return 1;
1796} 1876}
@@ -1798,19 +1878,29 @@ static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1798static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1878static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1799{ 1879{
1800 nsvm_printk("VMrun\n"); 1880 nsvm_printk("VMrun\n");
1881
1801 if (nested_svm_check_permissions(svm)) 1882 if (nested_svm_check_permissions(svm))
1802 return 1; 1883 return 1;
1803 1884
1804 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; 1885 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
1805 skip_emulated_instruction(&svm->vcpu); 1886 skip_emulated_instruction(&svm->vcpu);
1806 1887
1807 if (nested_svm_do(svm, svm->vmcb->save.rax, 0, 1888 if (!nested_svm_vmrun(svm))
1808 NULL, nested_svm_vmrun))
1809 return 1; 1889 return 1;
1810 1890
1811 if (nested_svm_do(svm, svm->nested_vmcb_msrpm, 0, 1891 if (!nested_svm_vmrun_msrpm(svm))
1812 NULL, nested_svm_vmrun_msrpm)) 1892 goto failed;
1813 return 1; 1893
1894 return 1;
1895
1896failed:
1897
1898 svm->vmcb->control.exit_code = SVM_EXIT_ERR;
1899 svm->vmcb->control.exit_code_hi = 0;
1900 svm->vmcb->control.exit_info_1 = 0;
1901 svm->vmcb->control.exit_info_2 = 0;
1902
1903 nested_svm_vmexit(svm);
1814 1904
1815 return 1; 1905 return 1;
1816} 1906}
@@ -1823,7 +1913,7 @@ static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1823 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; 1913 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
1824 skip_emulated_instruction(&svm->vcpu); 1914 skip_emulated_instruction(&svm->vcpu);
1825 1915
1826 svm->vcpu.arch.hflags |= HF_GIF_MASK; 1916 enable_gif(svm);
1827 1917
1828 return 1; 1918 return 1;
1829} 1919}
@@ -1836,7 +1926,7 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1836 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; 1926 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
1837 skip_emulated_instruction(&svm->vcpu); 1927 skip_emulated_instruction(&svm->vcpu);
1838 1928
1839 svm->vcpu.arch.hflags &= ~HF_GIF_MASK; 1929 disable_gif(svm);
1840 1930
1841 /* After a CLGI no interrupts should come */ 1931 /* After a CLGI no interrupts should come */
1842 svm_clear_vintr(svm); 1932 svm_clear_vintr(svm);
@@ -1845,6 +1935,19 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1845 return 1; 1935 return 1;
1846} 1936}
1847 1937
1938static int invlpga_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1939{
1940 struct kvm_vcpu *vcpu = &svm->vcpu;
1941 nsvm_printk("INVLPGA\n");
1942
1943 /* Let's treat INVLPGA the same as INVLPG (can be optimized!) */
1944 kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]);
1945
1946 svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
1947 skip_emulated_instruction(&svm->vcpu);
1948 return 1;
1949}
1950
1848static int invalid_op_interception(struct vcpu_svm *svm, 1951static int invalid_op_interception(struct vcpu_svm *svm,
1849 struct kvm_run *kvm_run) 1952 struct kvm_run *kvm_run)
1850{ 1953{
@@ -1953,7 +2056,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
1953 struct vcpu_svm *svm = to_svm(vcpu); 2056 struct vcpu_svm *svm = to_svm(vcpu);
1954 2057
1955 switch (ecx) { 2058 switch (ecx) {
1956 case MSR_IA32_TIME_STAMP_COUNTER: { 2059 case MSR_IA32_TSC: {
1957 u64 tsc; 2060 u64 tsc;
1958 2061
1959 rdtscll(tsc); 2062 rdtscll(tsc);
@@ -1981,10 +2084,10 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
1981 *data = svm->vmcb->save.sysenter_cs; 2084 *data = svm->vmcb->save.sysenter_cs;
1982 break; 2085 break;
1983 case MSR_IA32_SYSENTER_EIP: 2086 case MSR_IA32_SYSENTER_EIP:
1984 *data = svm->vmcb->save.sysenter_eip; 2087 *data = svm->sysenter_eip;
1985 break; 2088 break;
1986 case MSR_IA32_SYSENTER_ESP: 2089 case MSR_IA32_SYSENTER_ESP:
1987 *data = svm->vmcb->save.sysenter_esp; 2090 *data = svm->sysenter_esp;
1988 break; 2091 break;
1989 /* Nobody will change the following 5 values in the VMCB so 2092 /* Nobody will change the following 5 values in the VMCB so
1990 we can safely return them on rdmsr. They will always be 0 2093 we can safely return them on rdmsr. They will always be 0
@@ -2005,7 +2108,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
2005 *data = svm->vmcb->save.last_excp_to; 2108 *data = svm->vmcb->save.last_excp_to;
2006 break; 2109 break;
2007 case MSR_VM_HSAVE_PA: 2110 case MSR_VM_HSAVE_PA:
2008 *data = svm->hsave_msr; 2111 *data = svm->nested.hsave_msr;
2009 break; 2112 break;
2010 case MSR_VM_CR: 2113 case MSR_VM_CR:
2011 *data = 0; 2114 *data = 0;
@@ -2027,8 +2130,7 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
2027 if (svm_get_msr(&svm->vcpu, ecx, &data)) 2130 if (svm_get_msr(&svm->vcpu, ecx, &data))
2028 kvm_inject_gp(&svm->vcpu, 0); 2131 kvm_inject_gp(&svm->vcpu, 0);
2029 else { 2132 else {
2030 KVMTRACE_3D(MSR_READ, &svm->vcpu, ecx, (u32)data, 2133 trace_kvm_msr_read(ecx, data);
2031 (u32)(data >> 32), handler);
2032 2134
2033 svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; 2135 svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
2034 svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; 2136 svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32;
@@ -2043,7 +2145,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
2043 struct vcpu_svm *svm = to_svm(vcpu); 2145 struct vcpu_svm *svm = to_svm(vcpu);
2044 2146
2045 switch (ecx) { 2147 switch (ecx) {
2046 case MSR_IA32_TIME_STAMP_COUNTER: { 2148 case MSR_IA32_TSC: {
2047 u64 tsc; 2149 u64 tsc;
2048 2150
2049 rdtscll(tsc); 2151 rdtscll(tsc);
@@ -2071,9 +2173,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
2071 svm->vmcb->save.sysenter_cs = data; 2173 svm->vmcb->save.sysenter_cs = data;
2072 break; 2174 break;
2073 case MSR_IA32_SYSENTER_EIP: 2175 case MSR_IA32_SYSENTER_EIP:
2176 svm->sysenter_eip = data;
2074 svm->vmcb->save.sysenter_eip = data; 2177 svm->vmcb->save.sysenter_eip = data;
2075 break; 2178 break;
2076 case MSR_IA32_SYSENTER_ESP: 2179 case MSR_IA32_SYSENTER_ESP:
2180 svm->sysenter_esp = data;
2077 svm->vmcb->save.sysenter_esp = data; 2181 svm->vmcb->save.sysenter_esp = data;
2078 break; 2182 break;
2079 case MSR_IA32_DEBUGCTLMSR: 2183 case MSR_IA32_DEBUGCTLMSR:
@@ -2091,24 +2195,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
2091 else 2195 else
2092 svm_disable_lbrv(svm); 2196 svm_disable_lbrv(svm);
2093 break; 2197 break;
2094 case MSR_K7_EVNTSEL0:
2095 case MSR_K7_EVNTSEL1:
2096 case MSR_K7_EVNTSEL2:
2097 case MSR_K7_EVNTSEL3:
2098 case MSR_K7_PERFCTR0:
2099 case MSR_K7_PERFCTR1:
2100 case MSR_K7_PERFCTR2:
2101 case MSR_K7_PERFCTR3:
2102 /*
2103 * Just discard all writes to the performance counters; this
2104 * should keep both older linux and windows 64-bit guests
2105 * happy
2106 */
2107 pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", ecx, data);
2108
2109 break;
2110 case MSR_VM_HSAVE_PA: 2198 case MSR_VM_HSAVE_PA:
2111 svm->hsave_msr = data; 2199 svm->nested.hsave_msr = data;
2200 break;
2201 case MSR_VM_CR:
2202 case MSR_VM_IGNNE:
2203 pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
2112 break; 2204 break;
2113 default: 2205 default:
2114 return kvm_set_msr_common(vcpu, ecx, data); 2206 return kvm_set_msr_common(vcpu, ecx, data);
@@ -2122,8 +2214,7 @@ static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
2122 u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) 2214 u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
2123 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); 2215 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
2124 2216
2125 KVMTRACE_3D(MSR_WRITE, &svm->vcpu, ecx, (u32)data, (u32)(data >> 32), 2217 trace_kvm_msr_write(ecx, data);
2126 handler);
2127 2218
2128 svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; 2219 svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
2129 if (svm_set_msr(&svm->vcpu, ecx, data)) 2220 if (svm_set_msr(&svm->vcpu, ecx, data))
@@ -2144,8 +2235,6 @@ static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
2144static int interrupt_window_interception(struct vcpu_svm *svm, 2235static int interrupt_window_interception(struct vcpu_svm *svm,
2145 struct kvm_run *kvm_run) 2236 struct kvm_run *kvm_run)
2146{ 2237{
2147 KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler);
2148
2149 svm_clear_vintr(svm); 2238 svm_clear_vintr(svm);
2150 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; 2239 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
2151 /* 2240 /*
@@ -2201,7 +2290,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
2201 [SVM_EXIT_INVD] = emulate_on_interception, 2290 [SVM_EXIT_INVD] = emulate_on_interception,
2202 [SVM_EXIT_HLT] = halt_interception, 2291 [SVM_EXIT_HLT] = halt_interception,
2203 [SVM_EXIT_INVLPG] = invlpg_interception, 2292 [SVM_EXIT_INVLPG] = invlpg_interception,
2204 [SVM_EXIT_INVLPGA] = invalid_op_interception, 2293 [SVM_EXIT_INVLPGA] = invlpga_interception,
2205 [SVM_EXIT_IOIO] = io_interception, 2294 [SVM_EXIT_IOIO] = io_interception,
2206 [SVM_EXIT_MSR] = msr_interception, 2295 [SVM_EXIT_MSR] = msr_interception,
2207 [SVM_EXIT_TASK_SWITCH] = task_switch_interception, 2296 [SVM_EXIT_TASK_SWITCH] = task_switch_interception,
@@ -2224,20 +2313,26 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
2224 struct vcpu_svm *svm = to_svm(vcpu); 2313 struct vcpu_svm *svm = to_svm(vcpu);
2225 u32 exit_code = svm->vmcb->control.exit_code; 2314 u32 exit_code = svm->vmcb->control.exit_code;
2226 2315
2227 KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip, 2316 trace_kvm_exit(exit_code, svm->vmcb->save.rip);
2228 (u32)((u64)svm->vmcb->save.rip >> 32), entryexit);
2229 2317
2230 if (is_nested(svm)) { 2318 if (is_nested(svm)) {
2319 int vmexit;
2320
2231 nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n", 2321 nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n",
2232 exit_code, svm->vmcb->control.exit_info_1, 2322 exit_code, svm->vmcb->control.exit_info_1,
2233 svm->vmcb->control.exit_info_2, svm->vmcb->save.rip); 2323 svm->vmcb->control.exit_info_2, svm->vmcb->save.rip);
2234 if (nested_svm_exit_handled(svm, true)) { 2324
2235 nested_svm_vmexit(svm); 2325 vmexit = nested_svm_exit_special(svm);
2236 nsvm_printk("-> #VMEXIT\n"); 2326
2327 if (vmexit == NESTED_EXIT_CONTINUE)
2328 vmexit = nested_svm_exit_handled(svm);
2329
2330 if (vmexit == NESTED_EXIT_DONE)
2237 return 1; 2331 return 1;
2238 }
2239 } 2332 }
2240 2333
2334 svm_complete_interrupts(svm);
2335
2241 if (npt_enabled) { 2336 if (npt_enabled) {
2242 int mmu_reload = 0; 2337 int mmu_reload = 0;
2243 if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) { 2338 if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) {
@@ -2246,12 +2341,6 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
2246 } 2341 }
2247 vcpu->arch.cr0 = svm->vmcb->save.cr0; 2342 vcpu->arch.cr0 = svm->vmcb->save.cr0;
2248 vcpu->arch.cr3 = svm->vmcb->save.cr3; 2343 vcpu->arch.cr3 = svm->vmcb->save.cr3;
2249 if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
2250 if (!load_pdptrs(vcpu, vcpu->arch.cr3)) {
2251 kvm_inject_gp(vcpu, 0);
2252 return 1;
2253 }
2254 }
2255 if (mmu_reload) { 2344 if (mmu_reload) {
2256 kvm_mmu_reset_context(vcpu); 2345 kvm_mmu_reset_context(vcpu);
2257 kvm_mmu_load(vcpu); 2346 kvm_mmu_load(vcpu);
@@ -2319,7 +2408,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
2319{ 2408{
2320 struct vmcb_control_area *control; 2409 struct vmcb_control_area *control;
2321 2410
2322 KVMTRACE_1D(INJ_VIRQ, &svm->vcpu, (u32)irq, handler); 2411 trace_kvm_inj_virq(irq);
2323 2412
2324 ++svm->vcpu.stat.irq_injections; 2413 ++svm->vcpu.stat.irq_injections;
2325 control = &svm->vmcb->control; 2414 control = &svm->vmcb->control;
@@ -2329,21 +2418,14 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
2329 ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT); 2418 ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
2330} 2419}
2331 2420
2332static void svm_queue_irq(struct kvm_vcpu *vcpu, unsigned nr)
2333{
2334 struct vcpu_svm *svm = to_svm(vcpu);
2335
2336 svm->vmcb->control.event_inj = nr |
2337 SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR;
2338}
2339
2340static void svm_set_irq(struct kvm_vcpu *vcpu) 2421static void svm_set_irq(struct kvm_vcpu *vcpu)
2341{ 2422{
2342 struct vcpu_svm *svm = to_svm(vcpu); 2423 struct vcpu_svm *svm = to_svm(vcpu);
2343 2424
2344 nested_svm_intr(svm); 2425 BUG_ON(!(gif_set(svm)));
2345 2426
2346 svm_queue_irq(vcpu, vcpu->arch.interrupt.nr); 2427 svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr |
2428 SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR;
2347} 2429}
2348 2430
2349static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) 2431static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
@@ -2371,13 +2453,25 @@ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
2371 struct vmcb *vmcb = svm->vmcb; 2453 struct vmcb *vmcb = svm->vmcb;
2372 return (vmcb->save.rflags & X86_EFLAGS_IF) && 2454 return (vmcb->save.rflags & X86_EFLAGS_IF) &&
2373 !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) && 2455 !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
2374 (svm->vcpu.arch.hflags & HF_GIF_MASK); 2456 gif_set(svm) &&
2457 !(is_nested(svm) && (svm->vcpu.arch.hflags & HF_VINTR_MASK));
2375} 2458}
2376 2459
2377static void enable_irq_window(struct kvm_vcpu *vcpu) 2460static void enable_irq_window(struct kvm_vcpu *vcpu)
2378{ 2461{
2379 svm_set_vintr(to_svm(vcpu)); 2462 struct vcpu_svm *svm = to_svm(vcpu);
2380 svm_inject_irq(to_svm(vcpu), 0x0); 2463 nsvm_printk("Trying to open IRQ window\n");
2464
2465 nested_svm_intr(svm);
2466
2467 /* In case GIF=0 we can't rely on the CPU to tell us when
2468 * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
2469 * The next time we get that intercept, this function will be
2470 * called again though and we'll get the vintr intercept. */
2471 if (gif_set(svm)) {
2472 svm_set_vintr(svm);
2473 svm_inject_irq(svm, 0x0);
2474 }
2381} 2475}
2382 2476
2383static void enable_nmi_window(struct kvm_vcpu *vcpu) 2477static void enable_nmi_window(struct kvm_vcpu *vcpu)
@@ -2456,6 +2550,8 @@ static void svm_complete_interrupts(struct vcpu_svm *svm)
2456 case SVM_EXITINTINFO_TYPE_EXEPT: 2550 case SVM_EXITINTINFO_TYPE_EXEPT:
2457 /* In case of software exception do not reinject an exception 2551 /* In case of software exception do not reinject an exception
2458 vector, but re-execute and instruction instead */ 2552 vector, but re-execute and instruction instead */
2553 if (is_nested(svm))
2554 break;
2459 if (kvm_exception_is_soft(vector)) 2555 if (kvm_exception_is_soft(vector))
2460 break; 2556 break;
2461 if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { 2557 if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) {
@@ -2498,9 +2594,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2498 fs_selector = kvm_read_fs(); 2594 fs_selector = kvm_read_fs();
2499 gs_selector = kvm_read_gs(); 2595 gs_selector = kvm_read_gs();
2500 ldt_selector = kvm_read_ldt(); 2596 ldt_selector = kvm_read_ldt();
2501 svm->host_cr2 = kvm_read_cr2(); 2597 svm->vmcb->save.cr2 = vcpu->arch.cr2;
2502 if (!is_nested(svm))
2503 svm->vmcb->save.cr2 = vcpu->arch.cr2;
2504 /* required for live migration with NPT */ 2598 /* required for live migration with NPT */
2505 if (npt_enabled) 2599 if (npt_enabled)
2506 svm->vmcb->save.cr3 = vcpu->arch.cr3; 2600 svm->vmcb->save.cr3 = vcpu->arch.cr3;
@@ -2585,8 +2679,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2585 vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; 2679 vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
2586 vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; 2680 vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
2587 2681
2588 kvm_write_cr2(svm->host_cr2);
2589
2590 kvm_load_fs(fs_selector); 2682 kvm_load_fs(fs_selector);
2591 kvm_load_gs(gs_selector); 2683 kvm_load_gs(gs_selector);
2592 kvm_load_ldt(ldt_selector); 2684 kvm_load_ldt(ldt_selector);
@@ -2602,7 +2694,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2602 2694
2603 svm->next_rip = 0; 2695 svm->next_rip = 0;
2604 2696
2605 svm_complete_interrupts(svm); 2697 if (npt_enabled) {
2698 vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR);
2699 vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR);
2700 }
2606} 2701}
2607 2702
2608#undef R 2703#undef R
@@ -2673,6 +2768,64 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
2673 return 0; 2768 return 0;
2674} 2769}
2675 2770
2771static const struct trace_print_flags svm_exit_reasons_str[] = {
2772 { SVM_EXIT_READ_CR0, "read_cr0" },
2773 { SVM_EXIT_READ_CR3, "read_cr3" },
2774 { SVM_EXIT_READ_CR4, "read_cr4" },
2775 { SVM_EXIT_READ_CR8, "read_cr8" },
2776 { SVM_EXIT_WRITE_CR0, "write_cr0" },
2777 { SVM_EXIT_WRITE_CR3, "write_cr3" },
2778 { SVM_EXIT_WRITE_CR4, "write_cr4" },
2779 { SVM_EXIT_WRITE_CR8, "write_cr8" },
2780 { SVM_EXIT_READ_DR0, "read_dr0" },
2781 { SVM_EXIT_READ_DR1, "read_dr1" },
2782 { SVM_EXIT_READ_DR2, "read_dr2" },
2783 { SVM_EXIT_READ_DR3, "read_dr3" },
2784 { SVM_EXIT_WRITE_DR0, "write_dr0" },
2785 { SVM_EXIT_WRITE_DR1, "write_dr1" },
2786 { SVM_EXIT_WRITE_DR2, "write_dr2" },
2787 { SVM_EXIT_WRITE_DR3, "write_dr3" },
2788 { SVM_EXIT_WRITE_DR5, "write_dr5" },
2789 { SVM_EXIT_WRITE_DR7, "write_dr7" },
2790 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" },
2791 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" },
2792 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" },
2793 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" },
2794 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" },
2795 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" },
2796 { SVM_EXIT_INTR, "interrupt" },
2797 { SVM_EXIT_NMI, "nmi" },
2798 { SVM_EXIT_SMI, "smi" },
2799 { SVM_EXIT_INIT, "init" },
2800 { SVM_EXIT_VINTR, "vintr" },
2801 { SVM_EXIT_CPUID, "cpuid" },
2802 { SVM_EXIT_INVD, "invd" },
2803 { SVM_EXIT_HLT, "hlt" },
2804 { SVM_EXIT_INVLPG, "invlpg" },
2805 { SVM_EXIT_INVLPGA, "invlpga" },
2806 { SVM_EXIT_IOIO, "io" },
2807 { SVM_EXIT_MSR, "msr" },
2808 { SVM_EXIT_TASK_SWITCH, "task_switch" },
2809 { SVM_EXIT_SHUTDOWN, "shutdown" },
2810 { SVM_EXIT_VMRUN, "vmrun" },
2811 { SVM_EXIT_VMMCALL, "hypercall" },
2812 { SVM_EXIT_VMLOAD, "vmload" },
2813 { SVM_EXIT_VMSAVE, "vmsave" },
2814 { SVM_EXIT_STGI, "stgi" },
2815 { SVM_EXIT_CLGI, "clgi" },
2816 { SVM_EXIT_SKINIT, "skinit" },
2817 { SVM_EXIT_WBINVD, "wbinvd" },
2818 { SVM_EXIT_MONITOR, "monitor" },
2819 { SVM_EXIT_MWAIT, "mwait" },
2820 { SVM_EXIT_NPF, "npf" },
2821 { -1, NULL }
2822};
2823
2824static bool svm_gb_page_enable(void)
2825{
2826 return true;
2827}
2828
2676static struct kvm_x86_ops svm_x86_ops = { 2829static struct kvm_x86_ops svm_x86_ops = {
2677 .cpu_has_kvm_support = has_svm, 2830 .cpu_has_kvm_support = has_svm,
2678 .disabled_by_bios = is_disabled, 2831 .disabled_by_bios = is_disabled,
@@ -2710,6 +2863,7 @@ static struct kvm_x86_ops svm_x86_ops = {
2710 .set_gdt = svm_set_gdt, 2863 .set_gdt = svm_set_gdt,
2711 .get_dr = svm_get_dr, 2864 .get_dr = svm_get_dr,
2712 .set_dr = svm_set_dr, 2865 .set_dr = svm_set_dr,
2866 .cache_reg = svm_cache_reg,
2713 .get_rflags = svm_get_rflags, 2867 .get_rflags = svm_get_rflags,
2714 .set_rflags = svm_set_rflags, 2868 .set_rflags = svm_set_rflags,
2715 2869
@@ -2733,6 +2887,9 @@ static struct kvm_x86_ops svm_x86_ops = {
2733 .set_tss_addr = svm_set_tss_addr, 2887 .set_tss_addr = svm_set_tss_addr,
2734 .get_tdp_level = get_npt_level, 2888 .get_tdp_level = get_npt_level,
2735 .get_mt_mask = svm_get_mt_mask, 2889 .get_mt_mask = svm_get_mt_mask,
2890
2891 .exit_reasons_str = svm_exit_reasons_str,
2892 .gb_page_enable = svm_gb_page_enable,
2736}; 2893};
2737 2894
2738static int __init svm_init(void) 2895static int __init svm_init(void)
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c
index 86dbac072d0c..eea40439066c 100644
--- a/arch/x86/kvm/timer.c
+++ b/arch/x86/kvm/timer.c
@@ -9,12 +9,16 @@ static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
9 int restart_timer = 0; 9 int restart_timer = 0;
10 wait_queue_head_t *q = &vcpu->wq; 10 wait_queue_head_t *q = &vcpu->wq;
11 11
12 /* FIXME: this code should not know anything about vcpus */ 12 /*
13 if (!atomic_inc_and_test(&ktimer->pending)) 13 * There is a race window between reading and incrementing, but we do
14 * not care about potentially loosing timer events in the !reinject
15 * case anyway.
16 */
17 if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
18 atomic_inc(&ktimer->pending);
19 /* FIXME: this code should not know anything about vcpus */
14 set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); 20 set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
15 21 }
16 if (!ktimer->reinject)
17 atomic_set(&ktimer->pending, 1);
18 22
19 if (waitqueue_active(q)) 23 if (waitqueue_active(q))
20 wake_up_interruptible(q); 24 wake_up_interruptible(q);
@@ -33,7 +37,7 @@ enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
33 struct kvm_vcpu *vcpu; 37 struct kvm_vcpu *vcpu;
34 struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); 38 struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
35 39
36 vcpu = ktimer->kvm->vcpus[ktimer->vcpu_id]; 40 vcpu = ktimer->vcpu;
37 if (!vcpu) 41 if (!vcpu)
38 return HRTIMER_NORESTART; 42 return HRTIMER_NORESTART;
39 43
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
new file mode 100644
index 000000000000..0d480e77eacf
--- /dev/null
+++ b/arch/x86/kvm/trace.h
@@ -0,0 +1,355 @@
1#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
2#define _TRACE_KVM_H
3
4#include <linux/tracepoint.h>
5
6#undef TRACE_SYSTEM
7#define TRACE_SYSTEM kvm
8#define TRACE_INCLUDE_PATH arch/x86/kvm
9#define TRACE_INCLUDE_FILE trace
10
11/*
12 * Tracepoint for guest mode entry.
13 */
14TRACE_EVENT(kvm_entry,
15 TP_PROTO(unsigned int vcpu_id),
16 TP_ARGS(vcpu_id),
17
18 TP_STRUCT__entry(
19 __field( unsigned int, vcpu_id )
20 ),
21
22 TP_fast_assign(
23 __entry->vcpu_id = vcpu_id;
24 ),
25
26 TP_printk("vcpu %u", __entry->vcpu_id)
27);
28
29/*
30 * Tracepoint for hypercall.
31 */
32TRACE_EVENT(kvm_hypercall,
33 TP_PROTO(unsigned long nr, unsigned long a0, unsigned long a1,
34 unsigned long a2, unsigned long a3),
35 TP_ARGS(nr, a0, a1, a2, a3),
36
37 TP_STRUCT__entry(
38 __field( unsigned long, nr )
39 __field( unsigned long, a0 )
40 __field( unsigned long, a1 )
41 __field( unsigned long, a2 )
42 __field( unsigned long, a3 )
43 ),
44
45 TP_fast_assign(
46 __entry->nr = nr;
47 __entry->a0 = a0;
48 __entry->a1 = a1;
49 __entry->a2 = a2;
50 __entry->a3 = a3;
51 ),
52
53 TP_printk("nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx",
54 __entry->nr, __entry->a0, __entry->a1, __entry->a2,
55 __entry->a3)
56);
57
58/*
59 * Tracepoint for PIO.
60 */
61TRACE_EVENT(kvm_pio,
62 TP_PROTO(unsigned int rw, unsigned int port, unsigned int size,
63 unsigned int count),
64 TP_ARGS(rw, port, size, count),
65
66 TP_STRUCT__entry(
67 __field( unsigned int, rw )
68 __field( unsigned int, port )
69 __field( unsigned int, size )
70 __field( unsigned int, count )
71 ),
72
73 TP_fast_assign(
74 __entry->rw = rw;
75 __entry->port = port;
76 __entry->size = size;
77 __entry->count = count;
78 ),
79
80 TP_printk("pio_%s at 0x%x size %d count %d",
81 __entry->rw ? "write" : "read",
82 __entry->port, __entry->size, __entry->count)
83);
84
85/*
86 * Tracepoint for cpuid.
87 */
88TRACE_EVENT(kvm_cpuid,
89 TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx,
90 unsigned long rcx, unsigned long rdx),
91 TP_ARGS(function, rax, rbx, rcx, rdx),
92
93 TP_STRUCT__entry(
94 __field( unsigned int, function )
95 __field( unsigned long, rax )
96 __field( unsigned long, rbx )
97 __field( unsigned long, rcx )
98 __field( unsigned long, rdx )
99 ),
100
101 TP_fast_assign(
102 __entry->function = function;
103 __entry->rax = rax;
104 __entry->rbx = rbx;
105 __entry->rcx = rcx;
106 __entry->rdx = rdx;
107 ),
108
109 TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx",
110 __entry->function, __entry->rax,
111 __entry->rbx, __entry->rcx, __entry->rdx)
112);
113
114#define AREG(x) { APIC_##x, "APIC_" #x }
115
116#define kvm_trace_symbol_apic \
117 AREG(ID), AREG(LVR), AREG(TASKPRI), AREG(ARBPRI), AREG(PROCPRI), \
118 AREG(EOI), AREG(RRR), AREG(LDR), AREG(DFR), AREG(SPIV), AREG(ISR), \
119 AREG(TMR), AREG(IRR), AREG(ESR), AREG(ICR), AREG(ICR2), AREG(LVTT), \
120 AREG(LVTTHMR), AREG(LVTPC), AREG(LVT0), AREG(LVT1), AREG(LVTERR), \
121 AREG(TMICT), AREG(TMCCT), AREG(TDCR), AREG(SELF_IPI), AREG(EFEAT), \
122 AREG(ECTRL)
123/*
124 * Tracepoint for apic access.
125 */
126TRACE_EVENT(kvm_apic,
127 TP_PROTO(unsigned int rw, unsigned int reg, unsigned int val),
128 TP_ARGS(rw, reg, val),
129
130 TP_STRUCT__entry(
131 __field( unsigned int, rw )
132 __field( unsigned int, reg )
133 __field( unsigned int, val )
134 ),
135
136 TP_fast_assign(
137 __entry->rw = rw;
138 __entry->reg = reg;
139 __entry->val = val;
140 ),
141
142 TP_printk("apic_%s %s = 0x%x",
143 __entry->rw ? "write" : "read",
144 __print_symbolic(__entry->reg, kvm_trace_symbol_apic),
145 __entry->val)
146);
147
148#define trace_kvm_apic_read(reg, val) trace_kvm_apic(0, reg, val)
149#define trace_kvm_apic_write(reg, val) trace_kvm_apic(1, reg, val)
150
151/*
152 * Tracepoint for kvm guest exit:
153 */
154TRACE_EVENT(kvm_exit,
155 TP_PROTO(unsigned int exit_reason, unsigned long guest_rip),
156 TP_ARGS(exit_reason, guest_rip),
157
158 TP_STRUCT__entry(
159 __field( unsigned int, exit_reason )
160 __field( unsigned long, guest_rip )
161 ),
162
163 TP_fast_assign(
164 __entry->exit_reason = exit_reason;
165 __entry->guest_rip = guest_rip;
166 ),
167
168 TP_printk("reason %s rip 0x%lx",
169 ftrace_print_symbols_seq(p, __entry->exit_reason,
170 kvm_x86_ops->exit_reasons_str),
171 __entry->guest_rip)
172);
173
174/*
175 * Tracepoint for kvm interrupt injection:
176 */
177TRACE_EVENT(kvm_inj_virq,
178 TP_PROTO(unsigned int irq),
179 TP_ARGS(irq),
180
181 TP_STRUCT__entry(
182 __field( unsigned int, irq )
183 ),
184
185 TP_fast_assign(
186 __entry->irq = irq;
187 ),
188
189 TP_printk("irq %u", __entry->irq)
190);
191
192/*
193 * Tracepoint for page fault.
194 */
195TRACE_EVENT(kvm_page_fault,
196 TP_PROTO(unsigned long fault_address, unsigned int error_code),
197 TP_ARGS(fault_address, error_code),
198
199 TP_STRUCT__entry(
200 __field( unsigned long, fault_address )
201 __field( unsigned int, error_code )
202 ),
203
204 TP_fast_assign(
205 __entry->fault_address = fault_address;
206 __entry->error_code = error_code;
207 ),
208
209 TP_printk("address %lx error_code %x",
210 __entry->fault_address, __entry->error_code)
211);
212
213/*
214 * Tracepoint for guest MSR access.
215 */
216TRACE_EVENT(kvm_msr,
217 TP_PROTO(unsigned int rw, unsigned int ecx, unsigned long data),
218 TP_ARGS(rw, ecx, data),
219
220 TP_STRUCT__entry(
221 __field( unsigned int, rw )
222 __field( unsigned int, ecx )
223 __field( unsigned long, data )
224 ),
225
226 TP_fast_assign(
227 __entry->rw = rw;
228 __entry->ecx = ecx;
229 __entry->data = data;
230 ),
231
232 TP_printk("msr_%s %x = 0x%lx",
233 __entry->rw ? "write" : "read",
234 __entry->ecx, __entry->data)
235);
236
237#define trace_kvm_msr_read(ecx, data) trace_kvm_msr(0, ecx, data)
238#define trace_kvm_msr_write(ecx, data) trace_kvm_msr(1, ecx, data)
239
240/*
241 * Tracepoint for guest CR access.
242 */
243TRACE_EVENT(kvm_cr,
244 TP_PROTO(unsigned int rw, unsigned int cr, unsigned long val),
245 TP_ARGS(rw, cr, val),
246
247 TP_STRUCT__entry(
248 __field( unsigned int, rw )
249 __field( unsigned int, cr )
250 __field( unsigned long, val )
251 ),
252
253 TP_fast_assign(
254 __entry->rw = rw;
255 __entry->cr = cr;
256 __entry->val = val;
257 ),
258
259 TP_printk("cr_%s %x = 0x%lx",
260 __entry->rw ? "write" : "read",
261 __entry->cr, __entry->val)
262);
263
264#define trace_kvm_cr_read(cr, val) trace_kvm_cr(0, cr, val)
265#define trace_kvm_cr_write(cr, val) trace_kvm_cr(1, cr, val)
266
267TRACE_EVENT(kvm_pic_set_irq,
268 TP_PROTO(__u8 chip, __u8 pin, __u8 elcr, __u8 imr, bool coalesced),
269 TP_ARGS(chip, pin, elcr, imr, coalesced),
270
271 TP_STRUCT__entry(
272 __field( __u8, chip )
273 __field( __u8, pin )
274 __field( __u8, elcr )
275 __field( __u8, imr )
276 __field( bool, coalesced )
277 ),
278
279 TP_fast_assign(
280 __entry->chip = chip;
281 __entry->pin = pin;
282 __entry->elcr = elcr;
283 __entry->imr = imr;
284 __entry->coalesced = coalesced;
285 ),
286
287 TP_printk("chip %u pin %u (%s%s)%s",
288 __entry->chip, __entry->pin,
289 (__entry->elcr & (1 << __entry->pin)) ? "level":"edge",
290 (__entry->imr & (1 << __entry->pin)) ? "|masked":"",
291 __entry->coalesced ? " (coalesced)" : "")
292);
293
294#define kvm_apic_dst_shorthand \
295 {0x0, "dst"}, \
296 {0x1, "self"}, \
297 {0x2, "all"}, \
298 {0x3, "all-but-self"}
299
300TRACE_EVENT(kvm_apic_ipi,
301 TP_PROTO(__u32 icr_low, __u32 dest_id),
302 TP_ARGS(icr_low, dest_id),
303
304 TP_STRUCT__entry(
305 __field( __u32, icr_low )
306 __field( __u32, dest_id )
307 ),
308
309 TP_fast_assign(
310 __entry->icr_low = icr_low;
311 __entry->dest_id = dest_id;
312 ),
313
314 TP_printk("dst %x vec %u (%s|%s|%s|%s|%s)",
315 __entry->dest_id, (u8)__entry->icr_low,
316 __print_symbolic((__entry->icr_low >> 8 & 0x7),
317 kvm_deliver_mode),
318 (__entry->icr_low & (1<<11)) ? "logical" : "physical",
319 (__entry->icr_low & (1<<14)) ? "assert" : "de-assert",
320 (__entry->icr_low & (1<<15)) ? "level" : "edge",
321 __print_symbolic((__entry->icr_low >> 18 & 0x3),
322 kvm_apic_dst_shorthand))
323);
324
325TRACE_EVENT(kvm_apic_accept_irq,
326 TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec, bool coalesced),
327 TP_ARGS(apicid, dm, tm, vec, coalesced),
328
329 TP_STRUCT__entry(
330 __field( __u32, apicid )
331 __field( __u16, dm )
332 __field( __u8, tm )
333 __field( __u8, vec )
334 __field( bool, coalesced )
335 ),
336
337 TP_fast_assign(
338 __entry->apicid = apicid;
339 __entry->dm = dm;
340 __entry->tm = tm;
341 __entry->vec = vec;
342 __entry->coalesced = coalesced;
343 ),
344
345 TP_printk("apicid %x vec %u (%s|%s)%s",
346 __entry->apicid, __entry->vec,
347 __print_symbolic((__entry->dm >> 8 & 0x7), kvm_deliver_mode),
348 __entry->tm ? "level" : "edge",
349 __entry->coalesced ? " (coalesced)" : "")
350);
351
352#endif /* _TRACE_KVM_H */
353
354/* This part must be outside protection */
355#include <trace/define_trace.h>
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 29f912927a58..f3812014bd0b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -25,6 +25,7 @@
25#include <linux/highmem.h> 25#include <linux/highmem.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/ftrace_event.h>
28#include "kvm_cache_regs.h" 29#include "kvm_cache_regs.h"
29#include "x86.h" 30#include "x86.h"
30 31
@@ -34,6 +35,8 @@
34#include <asm/virtext.h> 35#include <asm/virtext.h>
35#include <asm/mce.h> 36#include <asm/mce.h>
36 37
38#include "trace.h"
39
37#define __ex(x) __kvm_handle_fault_on_reboot(x) 40#define __ex(x) __kvm_handle_fault_on_reboot(x)
38 41
39MODULE_AUTHOR("Qumranet"); 42MODULE_AUTHOR("Qumranet");
@@ -51,6 +54,10 @@ module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO);
51static int __read_mostly enable_ept = 1; 54static int __read_mostly enable_ept = 1;
52module_param_named(ept, enable_ept, bool, S_IRUGO); 55module_param_named(ept, enable_ept, bool, S_IRUGO);
53 56
57static int __read_mostly enable_unrestricted_guest = 1;
58module_param_named(unrestricted_guest,
59 enable_unrestricted_guest, bool, S_IRUGO);
60
54static int __read_mostly emulate_invalid_guest_state = 0; 61static int __read_mostly emulate_invalid_guest_state = 0;
55module_param(emulate_invalid_guest_state, bool, S_IRUGO); 62module_param(emulate_invalid_guest_state, bool, S_IRUGO);
56 63
@@ -84,6 +91,14 @@ struct vcpu_vmx {
84 int guest_efer_loaded; 91 int guest_efer_loaded;
85 } host_state; 92 } host_state;
86 struct { 93 struct {
94 int vm86_active;
95 u8 save_iopl;
96 struct kvm_save_segment {
97 u16 selector;
98 unsigned long base;
99 u32 limit;
100 u32 ar;
101 } tr, es, ds, fs, gs;
87 struct { 102 struct {
88 bool pending; 103 bool pending;
89 u8 vector; 104 u8 vector;
@@ -161,6 +176,8 @@ static struct kvm_vmx_segment_field {
161 VMX_SEGMENT_FIELD(LDTR), 176 VMX_SEGMENT_FIELD(LDTR),
162}; 177};
163 178
179static void ept_save_pdptrs(struct kvm_vcpu *vcpu);
180
164/* 181/*
165 * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it 182 * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
166 * away by decrementing the array size. 183 * away by decrementing the array size.
@@ -256,6 +273,26 @@ static inline bool cpu_has_vmx_flexpriority(void)
256 cpu_has_vmx_virtualize_apic_accesses(); 273 cpu_has_vmx_virtualize_apic_accesses();
257} 274}
258 275
276static inline bool cpu_has_vmx_ept_execute_only(void)
277{
278 return !!(vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT);
279}
280
281static inline bool cpu_has_vmx_eptp_uncacheable(void)
282{
283 return !!(vmx_capability.ept & VMX_EPTP_UC_BIT);
284}
285
286static inline bool cpu_has_vmx_eptp_writeback(void)
287{
288 return !!(vmx_capability.ept & VMX_EPTP_WB_BIT);
289}
290
291static inline bool cpu_has_vmx_ept_2m_page(void)
292{
293 return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT);
294}
295
259static inline int cpu_has_vmx_invept_individual_addr(void) 296static inline int cpu_has_vmx_invept_individual_addr(void)
260{ 297{
261 return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT); 298 return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
@@ -277,6 +314,12 @@ static inline int cpu_has_vmx_ept(void)
277 SECONDARY_EXEC_ENABLE_EPT; 314 SECONDARY_EXEC_ENABLE_EPT;
278} 315}
279 316
317static inline int cpu_has_vmx_unrestricted_guest(void)
318{
319 return vmcs_config.cpu_based_2nd_exec_ctrl &
320 SECONDARY_EXEC_UNRESTRICTED_GUEST;
321}
322
280static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) 323static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
281{ 324{
282 return flexpriority_enabled && 325 return flexpriority_enabled &&
@@ -497,14 +540,16 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
497 eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR); 540 eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
498 if (!vcpu->fpu_active) 541 if (!vcpu->fpu_active)
499 eb |= 1u << NM_VECTOR; 542 eb |= 1u << NM_VECTOR;
543 /*
544 * Unconditionally intercept #DB so we can maintain dr6 without
545 * reading it every exit.
546 */
547 eb |= 1u << DB_VECTOR;
500 if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { 548 if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
501 if (vcpu->guest_debug &
502 (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
503 eb |= 1u << DB_VECTOR;
504 if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) 549 if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
505 eb |= 1u << BP_VECTOR; 550 eb |= 1u << BP_VECTOR;
506 } 551 }
507 if (vcpu->arch.rmode.vm86_active) 552 if (to_vmx(vcpu)->rmode.vm86_active)
508 eb = ~0; 553 eb = ~0;
509 if (enable_ept) 554 if (enable_ept)
510 eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ 555 eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
@@ -528,12 +573,15 @@ static void reload_tss(void)
528static void load_transition_efer(struct vcpu_vmx *vmx) 573static void load_transition_efer(struct vcpu_vmx *vmx)
529{ 574{
530 int efer_offset = vmx->msr_offset_efer; 575 int efer_offset = vmx->msr_offset_efer;
531 u64 host_efer = vmx->host_msrs[efer_offset].data; 576 u64 host_efer;
532 u64 guest_efer = vmx->guest_msrs[efer_offset].data; 577 u64 guest_efer;
533 u64 ignore_bits; 578 u64 ignore_bits;
534 579
535 if (efer_offset < 0) 580 if (efer_offset < 0)
536 return; 581 return;
582 host_efer = vmx->host_msrs[efer_offset].data;
583 guest_efer = vmx->guest_msrs[efer_offset].data;
584
537 /* 585 /*
538 * NX is emulated; LMA and LME handled by hardware; SCE meaninless 586 * NX is emulated; LMA and LME handled by hardware; SCE meaninless
539 * outside long mode 587 * outside long mode
@@ -735,12 +783,17 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
735 783
736static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) 784static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
737{ 785{
738 return vmcs_readl(GUEST_RFLAGS); 786 unsigned long rflags;
787
788 rflags = vmcs_readl(GUEST_RFLAGS);
789 if (to_vmx(vcpu)->rmode.vm86_active)
790 rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
791 return rflags;
739} 792}
740 793
741static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) 794static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
742{ 795{
743 if (vcpu->arch.rmode.vm86_active) 796 if (to_vmx(vcpu)->rmode.vm86_active)
744 rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; 797 rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
745 vmcs_writel(GUEST_RFLAGS, rflags); 798 vmcs_writel(GUEST_RFLAGS, rflags);
746} 799}
@@ -797,12 +850,13 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
797 intr_info |= INTR_INFO_DELIVER_CODE_MASK; 850 intr_info |= INTR_INFO_DELIVER_CODE_MASK;
798 } 851 }
799 852
800 if (vcpu->arch.rmode.vm86_active) { 853 if (vmx->rmode.vm86_active) {
801 vmx->rmode.irq.pending = true; 854 vmx->rmode.irq.pending = true;
802 vmx->rmode.irq.vector = nr; 855 vmx->rmode.irq.vector = nr;
803 vmx->rmode.irq.rip = kvm_rip_read(vcpu); 856 vmx->rmode.irq.rip = kvm_rip_read(vcpu);
804 if (nr == BP_VECTOR || nr == OF_VECTOR) 857 if (kvm_exception_is_soft(nr))
805 vmx->rmode.irq.rip++; 858 vmx->rmode.irq.rip +=
859 vmx->vcpu.arch.event_exit_inst_len;
806 intr_info |= INTR_TYPE_SOFT_INTR; 860 intr_info |= INTR_TYPE_SOFT_INTR;
807 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); 861 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
808 vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); 862 vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
@@ -940,7 +994,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
940 case MSR_EFER: 994 case MSR_EFER:
941 return kvm_get_msr_common(vcpu, msr_index, pdata); 995 return kvm_get_msr_common(vcpu, msr_index, pdata);
942#endif 996#endif
943 case MSR_IA32_TIME_STAMP_COUNTER: 997 case MSR_IA32_TSC:
944 data = guest_read_tsc(); 998 data = guest_read_tsc();
945 break; 999 break;
946 case MSR_IA32_SYSENTER_CS: 1000 case MSR_IA32_SYSENTER_CS:
@@ -953,9 +1007,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
953 data = vmcs_readl(GUEST_SYSENTER_ESP); 1007 data = vmcs_readl(GUEST_SYSENTER_ESP);
954 break; 1008 break;
955 default: 1009 default:
956 vmx_load_host_state(to_vmx(vcpu));
957 msr = find_msr_entry(to_vmx(vcpu), msr_index); 1010 msr = find_msr_entry(to_vmx(vcpu), msr_index);
958 if (msr) { 1011 if (msr) {
1012 vmx_load_host_state(to_vmx(vcpu));
959 data = msr->data; 1013 data = msr->data;
960 break; 1014 break;
961 } 1015 }
@@ -1000,22 +1054,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
1000 case MSR_IA32_SYSENTER_ESP: 1054 case MSR_IA32_SYSENTER_ESP:
1001 vmcs_writel(GUEST_SYSENTER_ESP, data); 1055 vmcs_writel(GUEST_SYSENTER_ESP, data);
1002 break; 1056 break;
1003 case MSR_IA32_TIME_STAMP_COUNTER: 1057 case MSR_IA32_TSC:
1004 rdtscll(host_tsc); 1058 rdtscll(host_tsc);
1005 guest_write_tsc(data, host_tsc); 1059 guest_write_tsc(data, host_tsc);
1006 break; 1060 break;
1007 case MSR_P6_PERFCTR0:
1008 case MSR_P6_PERFCTR1:
1009 case MSR_P6_EVNTSEL0:
1010 case MSR_P6_EVNTSEL1:
1011 /*
1012 * Just discard all writes to the performance counters; this
1013 * should keep both older linux and windows 64-bit guests
1014 * happy
1015 */
1016 pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", msr_index, data);
1017
1018 break;
1019 case MSR_IA32_CR_PAT: 1061 case MSR_IA32_CR_PAT:
1020 if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { 1062 if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
1021 vmcs_write64(GUEST_IA32_PAT, data); 1063 vmcs_write64(GUEST_IA32_PAT, data);
@@ -1024,9 +1066,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
1024 } 1066 }
1025 /* Otherwise falls through to kvm_set_msr_common */ 1067 /* Otherwise falls through to kvm_set_msr_common */
1026 default: 1068 default:
1027 vmx_load_host_state(vmx);
1028 msr = find_msr_entry(vmx, msr_index); 1069 msr = find_msr_entry(vmx, msr_index);
1029 if (msr) { 1070 if (msr) {
1071 vmx_load_host_state(vmx);
1030 msr->data = data; 1072 msr->data = data;
1031 break; 1073 break;
1032 } 1074 }
@@ -1046,6 +1088,10 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
1046 case VCPU_REGS_RIP: 1088 case VCPU_REGS_RIP:
1047 vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP); 1089 vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP);
1048 break; 1090 break;
1091 case VCPU_EXREG_PDPTR:
1092 if (enable_ept)
1093 ept_save_pdptrs(vcpu);
1094 break;
1049 default: 1095 default:
1050 break; 1096 break;
1051 } 1097 }
@@ -1203,7 +1249,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
1203 opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | 1249 opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
1204 SECONDARY_EXEC_WBINVD_EXITING | 1250 SECONDARY_EXEC_WBINVD_EXITING |
1205 SECONDARY_EXEC_ENABLE_VPID | 1251 SECONDARY_EXEC_ENABLE_VPID |
1206 SECONDARY_EXEC_ENABLE_EPT; 1252 SECONDARY_EXEC_ENABLE_EPT |
1253 SECONDARY_EXEC_UNRESTRICTED_GUEST;
1207 if (adjust_vmx_controls(min2, opt2, 1254 if (adjust_vmx_controls(min2, opt2,
1208 MSR_IA32_VMX_PROCBASED_CTLS2, 1255 MSR_IA32_VMX_PROCBASED_CTLS2,
1209 &_cpu_based_2nd_exec_control) < 0) 1256 &_cpu_based_2nd_exec_control) < 0)
@@ -1217,12 +1264,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
1217 if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { 1264 if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
1218 /* CR3 accesses and invlpg don't need to cause VM Exits when EPT 1265 /* CR3 accesses and invlpg don't need to cause VM Exits when EPT
1219 enabled */ 1266 enabled */
1220 min &= ~(CPU_BASED_CR3_LOAD_EXITING | 1267 _cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING |
1221 CPU_BASED_CR3_STORE_EXITING | 1268 CPU_BASED_CR3_STORE_EXITING |
1222 CPU_BASED_INVLPG_EXITING); 1269 CPU_BASED_INVLPG_EXITING);
1223 if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
1224 &_cpu_based_exec_control) < 0)
1225 return -EIO;
1226 rdmsr(MSR_IA32_VMX_EPT_VPID_CAP, 1270 rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
1227 vmx_capability.ept, vmx_capability.vpid); 1271 vmx_capability.ept, vmx_capability.vpid);
1228 } 1272 }
@@ -1333,8 +1377,13 @@ static __init int hardware_setup(void)
1333 if (!cpu_has_vmx_vpid()) 1377 if (!cpu_has_vmx_vpid())
1334 enable_vpid = 0; 1378 enable_vpid = 0;
1335 1379
1336 if (!cpu_has_vmx_ept()) 1380 if (!cpu_has_vmx_ept()) {
1337 enable_ept = 0; 1381 enable_ept = 0;
1382 enable_unrestricted_guest = 0;
1383 }
1384
1385 if (!cpu_has_vmx_unrestricted_guest())
1386 enable_unrestricted_guest = 0;
1338 1387
1339 if (!cpu_has_vmx_flexpriority()) 1388 if (!cpu_has_vmx_flexpriority())
1340 flexpriority_enabled = 0; 1389 flexpriority_enabled = 0;
@@ -1342,6 +1391,9 @@ static __init int hardware_setup(void)
1342 if (!cpu_has_vmx_tpr_shadow()) 1391 if (!cpu_has_vmx_tpr_shadow())
1343 kvm_x86_ops->update_cr8_intercept = NULL; 1392 kvm_x86_ops->update_cr8_intercept = NULL;
1344 1393
1394 if (enable_ept && !cpu_has_vmx_ept_2m_page())
1395 kvm_disable_largepages();
1396
1345 return alloc_kvm_area(); 1397 return alloc_kvm_area();
1346} 1398}
1347 1399
@@ -1372,15 +1424,15 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
1372 struct vcpu_vmx *vmx = to_vmx(vcpu); 1424 struct vcpu_vmx *vmx = to_vmx(vcpu);
1373 1425
1374 vmx->emulation_required = 1; 1426 vmx->emulation_required = 1;
1375 vcpu->arch.rmode.vm86_active = 0; 1427 vmx->rmode.vm86_active = 0;
1376 1428
1377 vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base); 1429 vmcs_writel(GUEST_TR_BASE, vmx->rmode.tr.base);
1378 vmcs_write32(GUEST_TR_LIMIT, vcpu->arch.rmode.tr.limit); 1430 vmcs_write32(GUEST_TR_LIMIT, vmx->rmode.tr.limit);
1379 vmcs_write32(GUEST_TR_AR_BYTES, vcpu->arch.rmode.tr.ar); 1431 vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
1380 1432
1381 flags = vmcs_readl(GUEST_RFLAGS); 1433 flags = vmcs_readl(GUEST_RFLAGS);
1382 flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM); 1434 flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
1383 flags |= (vcpu->arch.rmode.save_iopl << IOPL_SHIFT); 1435 flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
1384 vmcs_writel(GUEST_RFLAGS, flags); 1436 vmcs_writel(GUEST_RFLAGS, flags);
1385 1437
1386 vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | 1438 vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1391,10 +1443,10 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
1391 if (emulate_invalid_guest_state) 1443 if (emulate_invalid_guest_state)
1392 return; 1444 return;
1393 1445
1394 fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es); 1446 fix_pmode_dataseg(VCPU_SREG_ES, &vmx->rmode.es);
1395 fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds); 1447 fix_pmode_dataseg(VCPU_SREG_DS, &vmx->rmode.ds);
1396 fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs); 1448 fix_pmode_dataseg(VCPU_SREG_GS, &vmx->rmode.gs);
1397 fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); 1449 fix_pmode_dataseg(VCPU_SREG_FS, &vmx->rmode.fs);
1398 1450
1399 vmcs_write16(GUEST_SS_SELECTOR, 0); 1451 vmcs_write16(GUEST_SS_SELECTOR, 0);
1400 vmcs_write32(GUEST_SS_AR_BYTES, 0x93); 1452 vmcs_write32(GUEST_SS_AR_BYTES, 0x93);
@@ -1433,20 +1485,23 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
1433 unsigned long flags; 1485 unsigned long flags;
1434 struct vcpu_vmx *vmx = to_vmx(vcpu); 1486 struct vcpu_vmx *vmx = to_vmx(vcpu);
1435 1487
1488 if (enable_unrestricted_guest)
1489 return;
1490
1436 vmx->emulation_required = 1; 1491 vmx->emulation_required = 1;
1437 vcpu->arch.rmode.vm86_active = 1; 1492 vmx->rmode.vm86_active = 1;
1438 1493
1439 vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE); 1494 vmx->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
1440 vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm)); 1495 vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
1441 1496
1442 vcpu->arch.rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT); 1497 vmx->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
1443 vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1); 1498 vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
1444 1499
1445 vcpu->arch.rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES); 1500 vmx->rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES);
1446 vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); 1501 vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
1447 1502
1448 flags = vmcs_readl(GUEST_RFLAGS); 1503 flags = vmcs_readl(GUEST_RFLAGS);
1449 vcpu->arch.rmode.save_iopl 1504 vmx->rmode.save_iopl
1450 = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; 1505 = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
1451 1506
1452 flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; 1507 flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
@@ -1468,10 +1523,10 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
1468 vmcs_writel(GUEST_CS_BASE, 0xf0000); 1523 vmcs_writel(GUEST_CS_BASE, 0xf0000);
1469 vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4); 1524 vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
1470 1525
1471 fix_rmode_seg(VCPU_SREG_ES, &vcpu->arch.rmode.es); 1526 fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
1472 fix_rmode_seg(VCPU_SREG_DS, &vcpu->arch.rmode.ds); 1527 fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
1473 fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs); 1528 fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
1474 fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); 1529 fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
1475 1530
1476continue_rmode: 1531continue_rmode:
1477 kvm_mmu_reset_context(vcpu); 1532 kvm_mmu_reset_context(vcpu);
@@ -1545,11 +1600,11 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
1545 1600
1546static void ept_load_pdptrs(struct kvm_vcpu *vcpu) 1601static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
1547{ 1602{
1603 if (!test_bit(VCPU_EXREG_PDPTR,
1604 (unsigned long *)&vcpu->arch.regs_dirty))
1605 return;
1606
1548 if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { 1607 if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
1549 if (!load_pdptrs(vcpu, vcpu->arch.cr3)) {
1550 printk(KERN_ERR "EPT: Fail to load pdptrs!\n");
1551 return;
1552 }
1553 vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); 1608 vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]);
1554 vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); 1609 vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]);
1555 vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); 1610 vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]);
@@ -1557,6 +1612,21 @@ static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
1557 } 1612 }
1558} 1613}
1559 1614
1615static void ept_save_pdptrs(struct kvm_vcpu *vcpu)
1616{
1617 if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
1618 vcpu->arch.pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
1619 vcpu->arch.pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
1620 vcpu->arch.pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
1621 vcpu->arch.pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
1622 }
1623
1624 __set_bit(VCPU_EXREG_PDPTR,
1625 (unsigned long *)&vcpu->arch.regs_avail);
1626 __set_bit(VCPU_EXREG_PDPTR,
1627 (unsigned long *)&vcpu->arch.regs_dirty);
1628}
1629
1560static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); 1630static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
1561 1631
1562static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, 1632static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
@@ -1571,8 +1641,6 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
1571 CPU_BASED_CR3_STORE_EXITING)); 1641 CPU_BASED_CR3_STORE_EXITING));
1572 vcpu->arch.cr0 = cr0; 1642 vcpu->arch.cr0 = cr0;
1573 vmx_set_cr4(vcpu, vcpu->arch.cr4); 1643 vmx_set_cr4(vcpu, vcpu->arch.cr4);
1574 *hw_cr0 |= X86_CR0_PE | X86_CR0_PG;
1575 *hw_cr0 &= ~X86_CR0_WP;
1576 } else if (!is_paging(vcpu)) { 1644 } else if (!is_paging(vcpu)) {
1577 /* From nonpaging to paging */ 1645 /* From nonpaging to paging */
1578 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, 1646 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
@@ -1581,9 +1649,10 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
1581 CPU_BASED_CR3_STORE_EXITING)); 1649 CPU_BASED_CR3_STORE_EXITING));
1582 vcpu->arch.cr0 = cr0; 1650 vcpu->arch.cr0 = cr0;
1583 vmx_set_cr4(vcpu, vcpu->arch.cr4); 1651 vmx_set_cr4(vcpu, vcpu->arch.cr4);
1584 if (!(vcpu->arch.cr0 & X86_CR0_WP))
1585 *hw_cr0 &= ~X86_CR0_WP;
1586 } 1652 }
1653
1654 if (!(cr0 & X86_CR0_WP))
1655 *hw_cr0 &= ~X86_CR0_WP;
1587} 1656}
1588 1657
1589static void ept_update_paging_mode_cr4(unsigned long *hw_cr4, 1658static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
@@ -1598,15 +1667,21 @@ static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
1598 1667
1599static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) 1668static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
1600{ 1669{
1601 unsigned long hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | 1670 struct vcpu_vmx *vmx = to_vmx(vcpu);
1602 KVM_VM_CR0_ALWAYS_ON; 1671 unsigned long hw_cr0;
1672
1673 if (enable_unrestricted_guest)
1674 hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST)
1675 | KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
1676 else
1677 hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON;
1603 1678
1604 vmx_fpu_deactivate(vcpu); 1679 vmx_fpu_deactivate(vcpu);
1605 1680
1606 if (vcpu->arch.rmode.vm86_active && (cr0 & X86_CR0_PE)) 1681 if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
1607 enter_pmode(vcpu); 1682 enter_pmode(vcpu);
1608 1683
1609 if (!vcpu->arch.rmode.vm86_active && !(cr0 & X86_CR0_PE)) 1684 if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE))
1610 enter_rmode(vcpu); 1685 enter_rmode(vcpu);
1611 1686
1612#ifdef CONFIG_X86_64 1687#ifdef CONFIG_X86_64
@@ -1650,10 +1725,8 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
1650 if (enable_ept) { 1725 if (enable_ept) {
1651 eptp = construct_eptp(cr3); 1726 eptp = construct_eptp(cr3);
1652 vmcs_write64(EPT_POINTER, eptp); 1727 vmcs_write64(EPT_POINTER, eptp);
1653 ept_sync_context(eptp);
1654 ept_load_pdptrs(vcpu);
1655 guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : 1728 guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
1656 VMX_EPT_IDENTITY_PAGETABLE_ADDR; 1729 vcpu->kvm->arch.ept_identity_map_addr;
1657 } 1730 }
1658 1731
1659 vmx_flush_tlb(vcpu); 1732 vmx_flush_tlb(vcpu);
@@ -1664,7 +1737,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
1664 1737
1665static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) 1738static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
1666{ 1739{
1667 unsigned long hw_cr4 = cr4 | (vcpu->arch.rmode.vm86_active ? 1740 unsigned long hw_cr4 = cr4 | (to_vmx(vcpu)->rmode.vm86_active ?
1668 KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON); 1741 KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
1669 1742
1670 vcpu->arch.cr4 = cr4; 1743 vcpu->arch.cr4 = cr4;
@@ -1707,16 +1780,13 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
1707 1780
1708static int vmx_get_cpl(struct kvm_vcpu *vcpu) 1781static int vmx_get_cpl(struct kvm_vcpu *vcpu)
1709{ 1782{
1710 struct kvm_segment kvm_seg;
1711
1712 if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */ 1783 if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */
1713 return 0; 1784 return 0;
1714 1785
1715 if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */ 1786 if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */
1716 return 3; 1787 return 3;
1717 1788
1718 vmx_get_segment(vcpu, &kvm_seg, VCPU_SREG_CS); 1789 return vmcs_read16(GUEST_CS_SELECTOR) & 3;
1719 return kvm_seg.selector & 3;
1720} 1790}
1721 1791
1722static u32 vmx_segment_access_rights(struct kvm_segment *var) 1792static u32 vmx_segment_access_rights(struct kvm_segment *var)
@@ -1744,20 +1814,21 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var)
1744static void vmx_set_segment(struct kvm_vcpu *vcpu, 1814static void vmx_set_segment(struct kvm_vcpu *vcpu,
1745 struct kvm_segment *var, int seg) 1815 struct kvm_segment *var, int seg)
1746{ 1816{
1817 struct vcpu_vmx *vmx = to_vmx(vcpu);
1747 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; 1818 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
1748 u32 ar; 1819 u32 ar;
1749 1820
1750 if (vcpu->arch.rmode.vm86_active && seg == VCPU_SREG_TR) { 1821 if (vmx->rmode.vm86_active && seg == VCPU_SREG_TR) {
1751 vcpu->arch.rmode.tr.selector = var->selector; 1822 vmx->rmode.tr.selector = var->selector;
1752 vcpu->arch.rmode.tr.base = var->base; 1823 vmx->rmode.tr.base = var->base;
1753 vcpu->arch.rmode.tr.limit = var->limit; 1824 vmx->rmode.tr.limit = var->limit;
1754 vcpu->arch.rmode.tr.ar = vmx_segment_access_rights(var); 1825 vmx->rmode.tr.ar = vmx_segment_access_rights(var);
1755 return; 1826 return;
1756 } 1827 }
1757 vmcs_writel(sf->base, var->base); 1828 vmcs_writel(sf->base, var->base);
1758 vmcs_write32(sf->limit, var->limit); 1829 vmcs_write32(sf->limit, var->limit);
1759 vmcs_write16(sf->selector, var->selector); 1830 vmcs_write16(sf->selector, var->selector);
1760 if (vcpu->arch.rmode.vm86_active && var->s) { 1831 if (vmx->rmode.vm86_active && var->s) {
1761 /* 1832 /*
1762 * Hack real-mode segments into vm86 compatibility. 1833 * Hack real-mode segments into vm86 compatibility.
1763 */ 1834 */
@@ -1766,6 +1837,21 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
1766 ar = 0xf3; 1837 ar = 0xf3;
1767 } else 1838 } else
1768 ar = vmx_segment_access_rights(var); 1839 ar = vmx_segment_access_rights(var);
1840
1841 /*
1842 * Fix the "Accessed" bit in AR field of segment registers for older
1843 * qemu binaries.
1844 * IA32 arch specifies that at the time of processor reset the
1845 * "Accessed" bit in the AR field of segment registers is 1. And qemu
1846 * is setting it to 0 in the usedland code. This causes invalid guest
1847 * state vmexit when "unrestricted guest" mode is turned on.
1848 * Fix for this setup issue in cpu_reset is being pushed in the qemu
1849 * tree. Newer qemu binaries with that qemu fix would not need this
1850 * kvm hack.
1851 */
1852 if (enable_unrestricted_guest && (seg != VCPU_SREG_LDTR))
1853 ar |= 0x1; /* Accessed */
1854
1769 vmcs_write32(sf->ar_bytes, ar); 1855 vmcs_write32(sf->ar_bytes, ar);
1770} 1856}
1771 1857
@@ -2040,7 +2126,7 @@ static int init_rmode_identity_map(struct kvm *kvm)
2040 if (likely(kvm->arch.ept_identity_pagetable_done)) 2126 if (likely(kvm->arch.ept_identity_pagetable_done))
2041 return 1; 2127 return 1;
2042 ret = 0; 2128 ret = 0;
2043 identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT; 2129 identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT;
2044 r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); 2130 r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
2045 if (r < 0) 2131 if (r < 0)
2046 goto out; 2132 goto out;
@@ -2062,11 +2148,19 @@ out:
2062static void seg_setup(int seg) 2148static void seg_setup(int seg)
2063{ 2149{
2064 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; 2150 struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
2151 unsigned int ar;
2065 2152
2066 vmcs_write16(sf->selector, 0); 2153 vmcs_write16(sf->selector, 0);
2067 vmcs_writel(sf->base, 0); 2154 vmcs_writel(sf->base, 0);
2068 vmcs_write32(sf->limit, 0xffff); 2155 vmcs_write32(sf->limit, 0xffff);
2069 vmcs_write32(sf->ar_bytes, 0xf3); 2156 if (enable_unrestricted_guest) {
2157 ar = 0x93;
2158 if (seg == VCPU_SREG_CS)
2159 ar |= 0x08; /* code segment */
2160 } else
2161 ar = 0xf3;
2162
2163 vmcs_write32(sf->ar_bytes, ar);
2070} 2164}
2071 2165
2072static int alloc_apic_access_page(struct kvm *kvm) 2166static int alloc_apic_access_page(struct kvm *kvm)
@@ -2101,14 +2195,15 @@ static int alloc_identity_pagetable(struct kvm *kvm)
2101 goto out; 2195 goto out;
2102 kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; 2196 kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
2103 kvm_userspace_mem.flags = 0; 2197 kvm_userspace_mem.flags = 0;
2104 kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR; 2198 kvm_userspace_mem.guest_phys_addr =
2199 kvm->arch.ept_identity_map_addr;
2105 kvm_userspace_mem.memory_size = PAGE_SIZE; 2200 kvm_userspace_mem.memory_size = PAGE_SIZE;
2106 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); 2201 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
2107 if (r) 2202 if (r)
2108 goto out; 2203 goto out;
2109 2204
2110 kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, 2205 kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
2111 VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT); 2206 kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
2112out: 2207out:
2113 up_write(&kvm->slots_lock); 2208 up_write(&kvm->slots_lock);
2114 return r; 2209 return r;
@@ -2209,6 +2304,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
2209 exec_control &= ~SECONDARY_EXEC_ENABLE_VPID; 2304 exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
2210 if (!enable_ept) 2305 if (!enable_ept)
2211 exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; 2306 exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
2307 if (!enable_unrestricted_guest)
2308 exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
2212 vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); 2309 vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
2213 } 2310 }
2214 2311
@@ -2326,14 +2423,14 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
2326 goto out; 2423 goto out;
2327 } 2424 }
2328 2425
2329 vmx->vcpu.arch.rmode.vm86_active = 0; 2426 vmx->rmode.vm86_active = 0;
2330 2427
2331 vmx->soft_vnmi_blocked = 0; 2428 vmx->soft_vnmi_blocked = 0;
2332 2429
2333 vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); 2430 vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
2334 kvm_set_cr8(&vmx->vcpu, 0); 2431 kvm_set_cr8(&vmx->vcpu, 0);
2335 msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; 2432 msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
2336 if (vmx->vcpu.vcpu_id == 0) 2433 if (kvm_vcpu_is_bsp(&vmx->vcpu))
2337 msr |= MSR_IA32_APICBASE_BSP; 2434 msr |= MSR_IA32_APICBASE_BSP;
2338 kvm_set_apic_base(&vmx->vcpu, msr); 2435 kvm_set_apic_base(&vmx->vcpu, msr);
2339 2436
@@ -2344,7 +2441,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
2344 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode 2441 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
2345 * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh. 2442 * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh.
2346 */ 2443 */
2347 if (vmx->vcpu.vcpu_id == 0) { 2444 if (kvm_vcpu_is_bsp(&vmx->vcpu)) {
2348 vmcs_write16(GUEST_CS_SELECTOR, 0xf000); 2445 vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
2349 vmcs_writel(GUEST_CS_BASE, 0x000f0000); 2446 vmcs_writel(GUEST_CS_BASE, 0x000f0000);
2350 } else { 2447 } else {
@@ -2373,7 +2470,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
2373 vmcs_writel(GUEST_SYSENTER_EIP, 0); 2470 vmcs_writel(GUEST_SYSENTER_EIP, 0);
2374 2471
2375 vmcs_writel(GUEST_RFLAGS, 0x02); 2472 vmcs_writel(GUEST_RFLAGS, 0x02);
2376 if (vmx->vcpu.vcpu_id == 0) 2473 if (kvm_vcpu_is_bsp(&vmx->vcpu))
2377 kvm_rip_write(vcpu, 0xfff0); 2474 kvm_rip_write(vcpu, 0xfff0);
2378 else 2475 else
2379 kvm_rip_write(vcpu, 0); 2476 kvm_rip_write(vcpu, 0);
@@ -2461,13 +2558,16 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
2461 uint32_t intr; 2558 uint32_t intr;
2462 int irq = vcpu->arch.interrupt.nr; 2559 int irq = vcpu->arch.interrupt.nr;
2463 2560
2464 KVMTRACE_1D(INJ_VIRQ, vcpu, (u32)irq, handler); 2561 trace_kvm_inj_virq(irq);
2465 2562
2466 ++vcpu->stat.irq_injections; 2563 ++vcpu->stat.irq_injections;
2467 if (vcpu->arch.rmode.vm86_active) { 2564 if (vmx->rmode.vm86_active) {
2468 vmx->rmode.irq.pending = true; 2565 vmx->rmode.irq.pending = true;
2469 vmx->rmode.irq.vector = irq; 2566 vmx->rmode.irq.vector = irq;
2470 vmx->rmode.irq.rip = kvm_rip_read(vcpu); 2567 vmx->rmode.irq.rip = kvm_rip_read(vcpu);
2568 if (vcpu->arch.interrupt.soft)
2569 vmx->rmode.irq.rip +=
2570 vmx->vcpu.arch.event_exit_inst_len;
2471 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 2571 vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
2472 irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); 2572 irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
2473 vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); 2573 vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
@@ -2502,7 +2602,7 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
2502 } 2602 }
2503 2603
2504 ++vcpu->stat.nmi_injections; 2604 ++vcpu->stat.nmi_injections;
2505 if (vcpu->arch.rmode.vm86_active) { 2605 if (vmx->rmode.vm86_active) {
2506 vmx->rmode.irq.pending = true; 2606 vmx->rmode.irq.pending = true;
2507 vmx->rmode.irq.vector = NMI_VECTOR; 2607 vmx->rmode.irq.vector = NMI_VECTOR;
2508 vmx->rmode.irq.rip = kvm_rip_read(vcpu); 2608 vmx->rmode.irq.rip = kvm_rip_read(vcpu);
@@ -2659,14 +2759,14 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2659 if (enable_ept) 2759 if (enable_ept)
2660 BUG(); 2760 BUG();
2661 cr2 = vmcs_readl(EXIT_QUALIFICATION); 2761 cr2 = vmcs_readl(EXIT_QUALIFICATION);
2662 KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, 2762 trace_kvm_page_fault(cr2, error_code);
2663 (u32)((u64)cr2 >> 32), handler); 2763
2664 if (kvm_event_needs_reinjection(vcpu)) 2764 if (kvm_event_needs_reinjection(vcpu))
2665 kvm_mmu_unprotect_page_virt(vcpu, cr2); 2765 kvm_mmu_unprotect_page_virt(vcpu, cr2);
2666 return kvm_mmu_page_fault(vcpu, cr2, error_code); 2766 return kvm_mmu_page_fault(vcpu, cr2, error_code);
2667 } 2767 }
2668 2768
2669 if (vcpu->arch.rmode.vm86_active && 2769 if (vmx->rmode.vm86_active &&
2670 handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, 2770 handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK,
2671 error_code)) { 2771 error_code)) {
2672 if (vcpu->arch.halt_request) { 2772 if (vcpu->arch.halt_request) {
@@ -2707,7 +2807,6 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu,
2707 struct kvm_run *kvm_run) 2807 struct kvm_run *kvm_run)
2708{ 2808{
2709 ++vcpu->stat.irq_exits; 2809 ++vcpu->stat.irq_exits;
2710 KVMTRACE_1D(INTR, vcpu, vmcs_read32(VM_EXIT_INTR_INFO), handler);
2711 return 1; 2810 return 1;
2712} 2811}
2713 2812
@@ -2755,7 +2854,7 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
2755 2854
2756static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 2855static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2757{ 2856{
2758 unsigned long exit_qualification; 2857 unsigned long exit_qualification, val;
2759 int cr; 2858 int cr;
2760 int reg; 2859 int reg;
2761 2860
@@ -2764,21 +2863,19 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2764 reg = (exit_qualification >> 8) & 15; 2863 reg = (exit_qualification >> 8) & 15;
2765 switch ((exit_qualification >> 4) & 3) { 2864 switch ((exit_qualification >> 4) & 3) {
2766 case 0: /* mov to cr */ 2865 case 0: /* mov to cr */
2767 KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, 2866 val = kvm_register_read(vcpu, reg);
2768 (u32)kvm_register_read(vcpu, reg), 2867 trace_kvm_cr_write(cr, val);
2769 (u32)((u64)kvm_register_read(vcpu, reg) >> 32),
2770 handler);
2771 switch (cr) { 2868 switch (cr) {
2772 case 0: 2869 case 0:
2773 kvm_set_cr0(vcpu, kvm_register_read(vcpu, reg)); 2870 kvm_set_cr0(vcpu, val);
2774 skip_emulated_instruction(vcpu); 2871 skip_emulated_instruction(vcpu);
2775 return 1; 2872 return 1;
2776 case 3: 2873 case 3:
2777 kvm_set_cr3(vcpu, kvm_register_read(vcpu, reg)); 2874 kvm_set_cr3(vcpu, val);
2778 skip_emulated_instruction(vcpu); 2875 skip_emulated_instruction(vcpu);
2779 return 1; 2876 return 1;
2780 case 4: 2877 case 4:
2781 kvm_set_cr4(vcpu, kvm_register_read(vcpu, reg)); 2878 kvm_set_cr4(vcpu, val);
2782 skip_emulated_instruction(vcpu); 2879 skip_emulated_instruction(vcpu);
2783 return 1; 2880 return 1;
2784 case 8: { 2881 case 8: {
@@ -2800,23 +2897,19 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2800 vcpu->arch.cr0 &= ~X86_CR0_TS; 2897 vcpu->arch.cr0 &= ~X86_CR0_TS;
2801 vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0); 2898 vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
2802 vmx_fpu_activate(vcpu); 2899 vmx_fpu_activate(vcpu);
2803 KVMTRACE_0D(CLTS, vcpu, handler);
2804 skip_emulated_instruction(vcpu); 2900 skip_emulated_instruction(vcpu);
2805 return 1; 2901 return 1;
2806 case 1: /*mov from cr*/ 2902 case 1: /*mov from cr*/
2807 switch (cr) { 2903 switch (cr) {
2808 case 3: 2904 case 3:
2809 kvm_register_write(vcpu, reg, vcpu->arch.cr3); 2905 kvm_register_write(vcpu, reg, vcpu->arch.cr3);
2810 KVMTRACE_3D(CR_READ, vcpu, (u32)cr, 2906 trace_kvm_cr_read(cr, vcpu->arch.cr3);
2811 (u32)kvm_register_read(vcpu, reg),
2812 (u32)((u64)kvm_register_read(vcpu, reg) >> 32),
2813 handler);
2814 skip_emulated_instruction(vcpu); 2907 skip_emulated_instruction(vcpu);
2815 return 1; 2908 return 1;
2816 case 8: 2909 case 8:
2817 kvm_register_write(vcpu, reg, kvm_get_cr8(vcpu)); 2910 val = kvm_get_cr8(vcpu);
2818 KVMTRACE_2D(CR_READ, vcpu, (u32)cr, 2911 kvm_register_write(vcpu, reg, val);
2819 (u32)kvm_register_read(vcpu, reg), handler); 2912 trace_kvm_cr_read(cr, val);
2820 skip_emulated_instruction(vcpu); 2913 skip_emulated_instruction(vcpu);
2821 return 1; 2914 return 1;
2822 } 2915 }
@@ -2841,6 +2934,8 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2841 unsigned long val; 2934 unsigned long val;
2842 int dr, reg; 2935 int dr, reg;
2843 2936
2937 if (!kvm_require_cpl(vcpu, 0))
2938 return 1;
2844 dr = vmcs_readl(GUEST_DR7); 2939 dr = vmcs_readl(GUEST_DR7);
2845 if (dr & DR7_GD) { 2940 if (dr & DR7_GD) {
2846 /* 2941 /*
@@ -2884,7 +2979,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2884 val = 0; 2979 val = 0;
2885 } 2980 }
2886 kvm_register_write(vcpu, reg, val); 2981 kvm_register_write(vcpu, reg, val);
2887 KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
2888 } else { 2982 } else {
2889 val = vcpu->arch.regs[reg]; 2983 val = vcpu->arch.regs[reg];
2890 switch (dr) { 2984 switch (dr) {
@@ -2917,7 +3011,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2917 } 3011 }
2918 break; 3012 break;
2919 } 3013 }
2920 KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)val, handler);
2921 } 3014 }
2922 skip_emulated_instruction(vcpu); 3015 skip_emulated_instruction(vcpu);
2923 return 1; 3016 return 1;
@@ -2939,8 +3032,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2939 return 1; 3032 return 1;
2940 } 3033 }
2941 3034
2942 KVMTRACE_3D(MSR_READ, vcpu, ecx, (u32)data, (u32)(data >> 32), 3035 trace_kvm_msr_read(ecx, data);
2943 handler);
2944 3036
2945 /* FIXME: handling of bits 32:63 of rax, rdx */ 3037 /* FIXME: handling of bits 32:63 of rax, rdx */
2946 vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u; 3038 vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u;
@@ -2955,8 +3047,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2955 u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) 3047 u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
2956 | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); 3048 | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
2957 3049
2958 KVMTRACE_3D(MSR_WRITE, vcpu, ecx, (u32)data, (u32)(data >> 32), 3050 trace_kvm_msr_write(ecx, data);
2959 handler);
2960 3051
2961 if (vmx_set_msr(vcpu, ecx, data) != 0) { 3052 if (vmx_set_msr(vcpu, ecx, data) != 0) {
2962 kvm_inject_gp(vcpu, 0); 3053 kvm_inject_gp(vcpu, 0);
@@ -2983,7 +3074,6 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu,
2983 cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; 3074 cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
2984 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); 3075 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
2985 3076
2986 KVMTRACE_0D(PEND_INTR, vcpu, handler);
2987 ++vcpu->stat.irq_window_exits; 3077 ++vcpu->stat.irq_window_exits;
2988 3078
2989 /* 3079 /*
@@ -3049,7 +3139,7 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3049 printk(KERN_ERR 3139 printk(KERN_ERR
3050 "Fail to handle apic access vmexit! Offset is 0x%lx\n", 3140 "Fail to handle apic access vmexit! Offset is 0x%lx\n",
3051 offset); 3141 offset);
3052 return -ENOTSUPP; 3142 return -ENOEXEC;
3053 } 3143 }
3054 return 1; 3144 return 1;
3055} 3145}
@@ -3118,7 +3208,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3118 3208
3119 if (exit_qualification & (1 << 6)) { 3209 if (exit_qualification & (1 << 6)) {
3120 printk(KERN_ERR "EPT: GPA exceeds GAW!\n"); 3210 printk(KERN_ERR "EPT: GPA exceeds GAW!\n");
3121 return -ENOTSUPP; 3211 return -EINVAL;
3122 } 3212 }
3123 3213
3124 gla_validity = (exit_qualification >> 7) & 0x3; 3214 gla_validity = (exit_qualification >> 7) & 0x3;
@@ -3130,14 +3220,98 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3130 printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n", 3220 printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
3131 (long unsigned int)exit_qualification); 3221 (long unsigned int)exit_qualification);
3132 kvm_run->exit_reason = KVM_EXIT_UNKNOWN; 3222 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
3133 kvm_run->hw.hardware_exit_reason = 0; 3223 kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_VIOLATION;
3134 return -ENOTSUPP; 3224 return 0;
3135 } 3225 }
3136 3226
3137 gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); 3227 gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
3228 trace_kvm_page_fault(gpa, exit_qualification);
3138 return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0); 3229 return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
3139} 3230}
3140 3231
3232static u64 ept_rsvd_mask(u64 spte, int level)
3233{
3234 int i;
3235 u64 mask = 0;
3236
3237 for (i = 51; i > boot_cpu_data.x86_phys_bits; i--)
3238 mask |= (1ULL << i);
3239
3240 if (level > 2)
3241 /* bits 7:3 reserved */
3242 mask |= 0xf8;
3243 else if (level == 2) {
3244 if (spte & (1ULL << 7))
3245 /* 2MB ref, bits 20:12 reserved */
3246 mask |= 0x1ff000;
3247 else
3248 /* bits 6:3 reserved */
3249 mask |= 0x78;
3250 }
3251
3252 return mask;
3253}
3254
3255static void ept_misconfig_inspect_spte(struct kvm_vcpu *vcpu, u64 spte,
3256 int level)
3257{
3258 printk(KERN_ERR "%s: spte 0x%llx level %d\n", __func__, spte, level);
3259
3260 /* 010b (write-only) */
3261 WARN_ON((spte & 0x7) == 0x2);
3262
3263 /* 110b (write/execute) */
3264 WARN_ON((spte & 0x7) == 0x6);
3265
3266 /* 100b (execute-only) and value not supported by logical processor */
3267 if (!cpu_has_vmx_ept_execute_only())
3268 WARN_ON((spte & 0x7) == 0x4);
3269
3270 /* not 000b */
3271 if ((spte & 0x7)) {
3272 u64 rsvd_bits = spte & ept_rsvd_mask(spte, level);
3273
3274 if (rsvd_bits != 0) {
3275 printk(KERN_ERR "%s: rsvd_bits = 0x%llx\n",
3276 __func__, rsvd_bits);
3277 WARN_ON(1);
3278 }
3279
3280 if (level == 1 || (level == 2 && (spte & (1ULL << 7)))) {
3281 u64 ept_mem_type = (spte & 0x38) >> 3;
3282
3283 if (ept_mem_type == 2 || ept_mem_type == 3 ||
3284 ept_mem_type == 7) {
3285 printk(KERN_ERR "%s: ept_mem_type=0x%llx\n",
3286 __func__, ept_mem_type);
3287 WARN_ON(1);
3288 }
3289 }
3290 }
3291}
3292
3293static int handle_ept_misconfig(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3294{
3295 u64 sptes[4];
3296 int nr_sptes, i;
3297 gpa_t gpa;
3298
3299 gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
3300
3301 printk(KERN_ERR "EPT: Misconfiguration.\n");
3302 printk(KERN_ERR "EPT: GPA: 0x%llx\n", gpa);
3303
3304 nr_sptes = kvm_mmu_get_spte_hierarchy(vcpu, gpa, sptes);
3305
3306 for (i = PT64_ROOT_LEVEL; i > PT64_ROOT_LEVEL - nr_sptes; --i)
3307 ept_misconfig_inspect_spte(vcpu, sptes[i-1], i);
3308
3309 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
3310 kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
3311
3312 return 0;
3313}
3314
3141static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 3315static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3142{ 3316{
3143 u32 cpu_based_vm_exec_control; 3317 u32 cpu_based_vm_exec_control;
@@ -3217,8 +3391,9 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
3217 [EXIT_REASON_APIC_ACCESS] = handle_apic_access, 3391 [EXIT_REASON_APIC_ACCESS] = handle_apic_access,
3218 [EXIT_REASON_WBINVD] = handle_wbinvd, 3392 [EXIT_REASON_WBINVD] = handle_wbinvd,
3219 [EXIT_REASON_TASK_SWITCH] = handle_task_switch, 3393 [EXIT_REASON_TASK_SWITCH] = handle_task_switch,
3220 [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation,
3221 [EXIT_REASON_MCE_DURING_VMENTRY] = handle_machine_check, 3394 [EXIT_REASON_MCE_DURING_VMENTRY] = handle_machine_check,
3395 [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation,
3396 [EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig,
3222}; 3397};
3223 3398
3224static const int kvm_vmx_max_exit_handlers = 3399static const int kvm_vmx_max_exit_handlers =
@@ -3234,8 +3409,7 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
3234 u32 exit_reason = vmx->exit_reason; 3409 u32 exit_reason = vmx->exit_reason;
3235 u32 vectoring_info = vmx->idt_vectoring_info; 3410 u32 vectoring_info = vmx->idt_vectoring_info;
3236 3411
3237 KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu), 3412 trace_kvm_exit(exit_reason, kvm_rip_read(vcpu));
3238 (u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit);
3239 3413
3240 /* If we need to emulate an MMIO from handle_invalid_guest_state 3414 /* If we need to emulate an MMIO from handle_invalid_guest_state
3241 * we just return 0 */ 3415 * we just return 0 */
@@ -3247,10 +3421,8 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
3247 3421
3248 /* Access CR3 don't cause VMExit in paging mode, so we need 3422 /* Access CR3 don't cause VMExit in paging mode, so we need
3249 * to sync with guest real CR3. */ 3423 * to sync with guest real CR3. */
3250 if (enable_ept && is_paging(vcpu)) { 3424 if (enable_ept && is_paging(vcpu))
3251 vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); 3425 vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
3252 ept_load_pdptrs(vcpu);
3253 }
3254 3426
3255 if (unlikely(vmx->fail)) { 3427 if (unlikely(vmx->fail)) {
3256 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; 3428 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
@@ -3326,10 +3498,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
3326 3498
3327 /* We need to handle NMIs before interrupts are enabled */ 3499 /* We need to handle NMIs before interrupts are enabled */
3328 if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && 3500 if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
3329 (exit_intr_info & INTR_INFO_VALID_MASK)) { 3501 (exit_intr_info & INTR_INFO_VALID_MASK))
3330 KVMTRACE_0D(NMI, &vmx->vcpu, handler);
3331 asm("int $2"); 3502 asm("int $2");
3332 }
3333 3503
3334 idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; 3504 idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
3335 3505
@@ -3434,6 +3604,10 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3434{ 3604{
3435 struct vcpu_vmx *vmx = to_vmx(vcpu); 3605 struct vcpu_vmx *vmx = to_vmx(vcpu);
3436 3606
3607 if (enable_ept && is_paging(vcpu)) {
3608 vmcs_writel(GUEST_CR3, vcpu->arch.cr3);
3609 ept_load_pdptrs(vcpu);
3610 }
3437 /* Record the guest's net vcpu time for enforced NMI injections. */ 3611 /* Record the guest's net vcpu time for enforced NMI injections. */
3438 if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) 3612 if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
3439 vmx->entry_time = ktime_get(); 3613 vmx->entry_time = ktime_get();
@@ -3449,12 +3623,21 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3449 if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) 3623 if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
3450 vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); 3624 vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
3451 3625
3626 /* When single-stepping over STI and MOV SS, we must clear the
3627 * corresponding interruptibility bits in the guest state. Otherwise
3628 * vmentry fails as it then expects bit 14 (BS) in pending debug
3629 * exceptions being set, but that's not correct for the guest debugging
3630 * case. */
3631 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
3632 vmx_set_interrupt_shadow(vcpu, 0);
3633
3452 /* 3634 /*
3453 * Loading guest fpu may have cleared host cr0.ts 3635 * Loading guest fpu may have cleared host cr0.ts
3454 */ 3636 */
3455 vmcs_writel(HOST_CR0, read_cr0()); 3637 vmcs_writel(HOST_CR0, read_cr0());
3456 3638
3457 set_debugreg(vcpu->arch.dr6, 6); 3639 if (vcpu->arch.switch_db_regs)
3640 set_debugreg(vcpu->arch.dr6, 6);
3458 3641
3459 asm( 3642 asm(
3460 /* Store host registers */ 3643 /* Store host registers */
@@ -3465,11 +3648,16 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3465 "mov %%"R"sp, %c[host_rsp](%0) \n\t" 3648 "mov %%"R"sp, %c[host_rsp](%0) \n\t"
3466 __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t" 3649 __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
3467 "1: \n\t" 3650 "1: \n\t"
3651 /* Reload cr2 if changed */
3652 "mov %c[cr2](%0), %%"R"ax \n\t"
3653 "mov %%cr2, %%"R"dx \n\t"
3654 "cmp %%"R"ax, %%"R"dx \n\t"
3655 "je 2f \n\t"
3656 "mov %%"R"ax, %%cr2 \n\t"
3657 "2: \n\t"
3468 /* Check if vmlaunch of vmresume is needed */ 3658 /* Check if vmlaunch of vmresume is needed */
3469 "cmpl $0, %c[launched](%0) \n\t" 3659 "cmpl $0, %c[launched](%0) \n\t"
3470 /* Load guest registers. Don't clobber flags. */ 3660 /* Load guest registers. Don't clobber flags. */
3471 "mov %c[cr2](%0), %%"R"ax \n\t"
3472 "mov %%"R"ax, %%cr2 \n\t"
3473 "mov %c[rax](%0), %%"R"ax \n\t" 3661 "mov %c[rax](%0), %%"R"ax \n\t"
3474 "mov %c[rbx](%0), %%"R"bx \n\t" 3662 "mov %c[rbx](%0), %%"R"bx \n\t"
3475 "mov %c[rdx](%0), %%"R"dx \n\t" 3663 "mov %c[rdx](%0), %%"R"dx \n\t"
@@ -3547,10 +3735,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3547#endif 3735#endif
3548 ); 3736 );
3549 3737
3550 vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)); 3738 vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
3739 | (1 << VCPU_EXREG_PDPTR));
3551 vcpu->arch.regs_dirty = 0; 3740 vcpu->arch.regs_dirty = 0;
3552 3741
3553 get_debugreg(vcpu->arch.dr6, 6); 3742 if (vcpu->arch.switch_db_regs)
3743 get_debugreg(vcpu->arch.dr6, 6);
3554 3744
3555 vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); 3745 vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
3556 if (vmx->rmode.irq.pending) 3746 if (vmx->rmode.irq.pending)
@@ -3633,9 +3823,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
3633 if (alloc_apic_access_page(kvm) != 0) 3823 if (alloc_apic_access_page(kvm) != 0)
3634 goto free_vmcs; 3824 goto free_vmcs;
3635 3825
3636 if (enable_ept) 3826 if (enable_ept) {
3827 if (!kvm->arch.ept_identity_map_addr)
3828 kvm->arch.ept_identity_map_addr =
3829 VMX_EPT_IDENTITY_PAGETABLE_ADDR;
3637 if (alloc_identity_pagetable(kvm) != 0) 3830 if (alloc_identity_pagetable(kvm) != 0)
3638 goto free_vmcs; 3831 goto free_vmcs;
3832 }
3639 3833
3640 return &vmx->vcpu; 3834 return &vmx->vcpu;
3641 3835
@@ -3699,6 +3893,34 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
3699 return ret; 3893 return ret;
3700} 3894}
3701 3895
3896static const struct trace_print_flags vmx_exit_reasons_str[] = {
3897 { EXIT_REASON_EXCEPTION_NMI, "exception" },
3898 { EXIT_REASON_EXTERNAL_INTERRUPT, "ext_irq" },
3899 { EXIT_REASON_TRIPLE_FAULT, "triple_fault" },
3900 { EXIT_REASON_NMI_WINDOW, "nmi_window" },
3901 { EXIT_REASON_IO_INSTRUCTION, "io_instruction" },
3902 { EXIT_REASON_CR_ACCESS, "cr_access" },
3903 { EXIT_REASON_DR_ACCESS, "dr_access" },
3904 { EXIT_REASON_CPUID, "cpuid" },
3905 { EXIT_REASON_MSR_READ, "rdmsr" },
3906 { EXIT_REASON_MSR_WRITE, "wrmsr" },
3907 { EXIT_REASON_PENDING_INTERRUPT, "interrupt_window" },
3908 { EXIT_REASON_HLT, "halt" },
3909 { EXIT_REASON_INVLPG, "invlpg" },
3910 { EXIT_REASON_VMCALL, "hypercall" },
3911 { EXIT_REASON_TPR_BELOW_THRESHOLD, "tpr_below_thres" },
3912 { EXIT_REASON_APIC_ACCESS, "apic_access" },
3913 { EXIT_REASON_WBINVD, "wbinvd" },
3914 { EXIT_REASON_TASK_SWITCH, "task_switch" },
3915 { EXIT_REASON_EPT_VIOLATION, "ept_violation" },
3916 { -1, NULL }
3917};
3918
3919static bool vmx_gb_page_enable(void)
3920{
3921 return false;
3922}
3923
3702static struct kvm_x86_ops vmx_x86_ops = { 3924static struct kvm_x86_ops vmx_x86_ops = {
3703 .cpu_has_kvm_support = cpu_has_kvm_support, 3925 .cpu_has_kvm_support = cpu_has_kvm_support,
3704 .disabled_by_bios = vmx_disabled_by_bios, 3926 .disabled_by_bios = vmx_disabled_by_bios,
@@ -3758,6 +3980,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
3758 .set_tss_addr = vmx_set_tss_addr, 3980 .set_tss_addr = vmx_set_tss_addr,
3759 .get_tdp_level = get_ept_level, 3981 .get_tdp_level = get_ept_level,
3760 .get_mt_mask = vmx_get_mt_mask, 3982 .get_mt_mask = vmx_get_mt_mask,
3983
3984 .exit_reasons_str = vmx_exit_reasons_str,
3985 .gb_page_enable = vmx_gb_page_enable,
3761}; 3986};
3762 3987
3763static int __init vmx_init(void) 3988static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3d4529011828..74029f50b26a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -37,11 +37,16 @@
37#include <linux/iommu.h> 37#include <linux/iommu.h>
38#include <linux/intel-iommu.h> 38#include <linux/intel-iommu.h>
39#include <linux/cpufreq.h> 39#include <linux/cpufreq.h>
40#include <trace/events/kvm.h>
41#undef TRACE_INCLUDE_FILE
42#define CREATE_TRACE_POINTS
43#include "trace.h"
40 44
41#include <asm/uaccess.h> 45#include <asm/uaccess.h>
42#include <asm/msr.h> 46#include <asm/msr.h>
43#include <asm/desc.h> 47#include <asm/desc.h>
44#include <asm/mtrr.h> 48#include <asm/mtrr.h>
49#include <asm/mce.h>
45 50
46#define MAX_IO_MSRS 256 51#define MAX_IO_MSRS 256
47#define CR0_RESERVED_BITS \ 52#define CR0_RESERVED_BITS \
@@ -55,6 +60,10 @@
55 | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) 60 | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
56 61
57#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) 62#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
63
64#define KVM_MAX_MCE_BANKS 32
65#define KVM_MCE_CAP_SUPPORTED MCG_CTL_P
66
58/* EFER defaults: 67/* EFER defaults:
59 * - enable syscall per default because its emulated by KVM 68 * - enable syscall per default because its emulated by KVM
60 * - enable LME and LMA per default on 64 bit KVM 69 * - enable LME and LMA per default on 64 bit KVM
@@ -68,14 +77,16 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;
68#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM 77#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
69#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU 78#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
70 79
80static void update_cr8_intercept(struct kvm_vcpu *vcpu);
71static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, 81static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
72 struct kvm_cpuid_entry2 __user *entries); 82 struct kvm_cpuid_entry2 __user *entries);
73struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
74 u32 function, u32 index);
75 83
76struct kvm_x86_ops *kvm_x86_ops; 84struct kvm_x86_ops *kvm_x86_ops;
77EXPORT_SYMBOL_GPL(kvm_x86_ops); 85EXPORT_SYMBOL_GPL(kvm_x86_ops);
78 86
87int ignore_msrs = 0;
88module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
89
79struct kvm_stats_debugfs_item debugfs_entries[] = { 90struct kvm_stats_debugfs_item debugfs_entries[] = {
80 { "pf_fixed", VCPU_STAT(pf_fixed) }, 91 { "pf_fixed", VCPU_STAT(pf_fixed) },
81 { "pf_guest", VCPU_STAT(pf_guest) }, 92 { "pf_guest", VCPU_STAT(pf_guest) },
@@ -122,18 +133,16 @@ unsigned long segment_base(u16 selector)
122 if (selector == 0) 133 if (selector == 0)
123 return 0; 134 return 0;
124 135
125 asm("sgdt %0" : "=m"(gdt)); 136 kvm_get_gdt(&gdt);
126 table_base = gdt.base; 137 table_base = gdt.base;
127 138
128 if (selector & 4) { /* from ldt */ 139 if (selector & 4) { /* from ldt */
129 u16 ldt_selector; 140 u16 ldt_selector = kvm_read_ldt();
130 141
131 asm("sldt %0" : "=g"(ldt_selector));
132 table_base = segment_base(ldt_selector); 142 table_base = segment_base(ldt_selector);
133 } 143 }
134 d = (struct desc_struct *)(table_base + (selector & ~7)); 144 d = (struct desc_struct *)(table_base + (selector & ~7));
135 v = d->base0 | ((unsigned long)d->base1 << 16) | 145 v = get_desc_base(d);
136 ((unsigned long)d->base2 << 24);
137#ifdef CONFIG_X86_64 146#ifdef CONFIG_X86_64
138 if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) 147 if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
139 v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; 148 v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
@@ -176,16 +185,22 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
176 ++vcpu->stat.pf_guest; 185 ++vcpu->stat.pf_guest;
177 186
178 if (vcpu->arch.exception.pending) { 187 if (vcpu->arch.exception.pending) {
179 if (vcpu->arch.exception.nr == PF_VECTOR) { 188 switch(vcpu->arch.exception.nr) {
180 printk(KERN_DEBUG "kvm: inject_page_fault:" 189 case DF_VECTOR:
181 " double fault 0x%lx\n", addr);
182 vcpu->arch.exception.nr = DF_VECTOR;
183 vcpu->arch.exception.error_code = 0;
184 } else if (vcpu->arch.exception.nr == DF_VECTOR) {
185 /* triple fault -> shutdown */ 190 /* triple fault -> shutdown */
186 set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); 191 set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
192 return;
193 case PF_VECTOR:
194 vcpu->arch.exception.nr = DF_VECTOR;
195 vcpu->arch.exception.error_code = 0;
196 return;
197 default:
198 /* replace previous exception with a new one in a hope
199 that instruction re-execution will regenerate lost
200 exception */
201 vcpu->arch.exception.pending = false;
202 break;
187 } 203 }
188 return;
189 } 204 }
190 vcpu->arch.cr2 = addr; 205 vcpu->arch.cr2 = addr;
191 kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); 206 kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
@@ -207,12 +222,18 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
207} 222}
208EXPORT_SYMBOL_GPL(kvm_queue_exception_e); 223EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
209 224
210static void __queue_exception(struct kvm_vcpu *vcpu) 225/*
226 * Checks if cpl <= required_cpl; if true, return true. Otherwise queue
227 * a #GP and return false.
228 */
229bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
211{ 230{
212 kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, 231 if (kvm_x86_ops->get_cpl(vcpu) <= required_cpl)
213 vcpu->arch.exception.has_error_code, 232 return true;
214 vcpu->arch.exception.error_code); 233 kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
234 return false;
215} 235}
236EXPORT_SYMBOL_GPL(kvm_require_cpl);
216 237
217/* 238/*
218 * Load the pae pdptrs. Return true is they are all valid. 239 * Load the pae pdptrs. Return true is they are all valid.
@@ -232,7 +253,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
232 goto out; 253 goto out;
233 } 254 }
234 for (i = 0; i < ARRAY_SIZE(pdpte); ++i) { 255 for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
235 if (is_present_pte(pdpte[i]) && 256 if (is_present_gpte(pdpte[i]) &&
236 (pdpte[i] & vcpu->arch.mmu.rsvd_bits_mask[0][2])) { 257 (pdpte[i] & vcpu->arch.mmu.rsvd_bits_mask[0][2])) {
237 ret = 0; 258 ret = 0;
238 goto out; 259 goto out;
@@ -241,6 +262,10 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
241 ret = 1; 262 ret = 1;
242 263
243 memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs)); 264 memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
265 __set_bit(VCPU_EXREG_PDPTR,
266 (unsigned long *)&vcpu->arch.regs_avail);
267 __set_bit(VCPU_EXREG_PDPTR,
268 (unsigned long *)&vcpu->arch.regs_dirty);
244out: 269out:
245 270
246 return ret; 271 return ret;
@@ -256,6 +281,10 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
256 if (is_long_mode(vcpu) || !is_pae(vcpu)) 281 if (is_long_mode(vcpu) || !is_pae(vcpu))
257 return false; 282 return false;
258 283
284 if (!test_bit(VCPU_EXREG_PDPTR,
285 (unsigned long *)&vcpu->arch.regs_avail))
286 return true;
287
259 r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte)); 288 r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
260 if (r < 0) 289 if (r < 0)
261 goto out; 290 goto out;
@@ -328,9 +357,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0);
328void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) 357void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
329{ 358{
330 kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); 359 kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f));
331 KVMTRACE_1D(LMSW, vcpu,
332 (u32)((vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)),
333 handler);
334} 360}
335EXPORT_SYMBOL_GPL(kvm_lmsw); 361EXPORT_SYMBOL_GPL(kvm_lmsw);
336 362
@@ -466,7 +492,7 @@ static u32 msrs_to_save[] = {
466#ifdef CONFIG_X86_64 492#ifdef CONFIG_X86_64
467 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, 493 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
468#endif 494#endif
469 MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, 495 MSR_IA32_TSC, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
470 MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA 496 MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
471}; 497};
472 498
@@ -644,8 +670,7 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
644 670
645 /* Keep irq disabled to prevent changes to the clock */ 671 /* Keep irq disabled to prevent changes to the clock */
646 local_irq_save(flags); 672 local_irq_save(flags);
647 kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, 673 kvm_get_msr(v, MSR_IA32_TSC, &vcpu->hv_clock.tsc_timestamp);
648 &vcpu->hv_clock.tsc_timestamp);
649 ktime_get_ts(&ts); 674 ktime_get_ts(&ts);
650 local_irq_restore(flags); 675 local_irq_restore(flags);
651 676
@@ -778,23 +803,60 @@ static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
778 return 0; 803 return 0;
779} 804}
780 805
806static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
807{
808 u64 mcg_cap = vcpu->arch.mcg_cap;
809 unsigned bank_num = mcg_cap & 0xff;
810
811 switch (msr) {
812 case MSR_IA32_MCG_STATUS:
813 vcpu->arch.mcg_status = data;
814 break;
815 case MSR_IA32_MCG_CTL:
816 if (!(mcg_cap & MCG_CTL_P))
817 return 1;
818 if (data != 0 && data != ~(u64)0)
819 return -1;
820 vcpu->arch.mcg_ctl = data;
821 break;
822 default:
823 if (msr >= MSR_IA32_MC0_CTL &&
824 msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
825 u32 offset = msr - MSR_IA32_MC0_CTL;
826 /* only 0 or all 1s can be written to IA32_MCi_CTL */
827 if ((offset & 0x3) == 0 &&
828 data != 0 && data != ~(u64)0)
829 return -1;
830 vcpu->arch.mce_banks[offset] = data;
831 break;
832 }
833 return 1;
834 }
835 return 0;
836}
837
781int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) 838int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
782{ 839{
783 switch (msr) { 840 switch (msr) {
784 case MSR_EFER: 841 case MSR_EFER:
785 set_efer(vcpu, data); 842 set_efer(vcpu, data);
786 break; 843 break;
787 case MSR_IA32_MC0_STATUS: 844 case MSR_K7_HWCR:
788 pr_unimpl(vcpu, "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n", 845 data &= ~(u64)0x40; /* ignore flush filter disable */
789 __func__, data); 846 if (data != 0) {
847 pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n",
848 data);
849 return 1;
850 }
790 break; 851 break;
791 case MSR_IA32_MCG_STATUS: 852 case MSR_FAM10H_MMIO_CONF_BASE:
792 pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n", 853 if (data != 0) {
793 __func__, data); 854 pr_unimpl(vcpu, "unimplemented MMIO_CONF_BASE wrmsr: "
855 "0x%llx\n", data);
856 return 1;
857 }
794 break; 858 break;
795 case MSR_IA32_MCG_CTL: 859 case MSR_AMD64_NB_CFG:
796 pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n",
797 __func__, data);
798 break; 860 break;
799 case MSR_IA32_DEBUGCTLMSR: 861 case MSR_IA32_DEBUGCTLMSR:
800 if (!data) { 862 if (!data) {
@@ -811,12 +873,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
811 case MSR_IA32_UCODE_REV: 873 case MSR_IA32_UCODE_REV:
812 case MSR_IA32_UCODE_WRITE: 874 case MSR_IA32_UCODE_WRITE:
813 case MSR_VM_HSAVE_PA: 875 case MSR_VM_HSAVE_PA:
876 case MSR_AMD64_PATCH_LOADER:
814 break; 877 break;
815 case 0x200 ... 0x2ff: 878 case 0x200 ... 0x2ff:
816 return set_msr_mtrr(vcpu, msr, data); 879 return set_msr_mtrr(vcpu, msr, data);
817 case MSR_IA32_APICBASE: 880 case MSR_IA32_APICBASE:
818 kvm_set_apic_base(vcpu, data); 881 kvm_set_apic_base(vcpu, data);
819 break; 882 break;
883 case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff:
884 return kvm_x2apic_msr_write(vcpu, msr, data);
820 case MSR_IA32_MISC_ENABLE: 885 case MSR_IA32_MISC_ENABLE:
821 vcpu->arch.ia32_misc_enable_msr = data; 886 vcpu->arch.ia32_misc_enable_msr = data;
822 break; 887 break;
@@ -850,9 +915,50 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
850 kvm_request_guest_time_update(vcpu); 915 kvm_request_guest_time_update(vcpu);
851 break; 916 break;
852 } 917 }
918 case MSR_IA32_MCG_CTL:
919 case MSR_IA32_MCG_STATUS:
920 case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
921 return set_msr_mce(vcpu, msr, data);
922
923 /* Performance counters are not protected by a CPUID bit,
924 * so we should check all of them in the generic path for the sake of
925 * cross vendor migration.
926 * Writing a zero into the event select MSRs disables them,
927 * which we perfectly emulate ;-). Any other value should be at least
928 * reported, some guests depend on them.
929 */
930 case MSR_P6_EVNTSEL0:
931 case MSR_P6_EVNTSEL1:
932 case MSR_K7_EVNTSEL0:
933 case MSR_K7_EVNTSEL1:
934 case MSR_K7_EVNTSEL2:
935 case MSR_K7_EVNTSEL3:
936 if (data != 0)
937 pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
938 "0x%x data 0x%llx\n", msr, data);
939 break;
940 /* at least RHEL 4 unconditionally writes to the perfctr registers,
941 * so we ignore writes to make it happy.
942 */
943 case MSR_P6_PERFCTR0:
944 case MSR_P6_PERFCTR1:
945 case MSR_K7_PERFCTR0:
946 case MSR_K7_PERFCTR1:
947 case MSR_K7_PERFCTR2:
948 case MSR_K7_PERFCTR3:
949 pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
950 "0x%x data 0x%llx\n", msr, data);
951 break;
853 default: 952 default:
854 pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data); 953 if (!ignore_msrs) {
855 return 1; 954 pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n",
955 msr, data);
956 return 1;
957 } else {
958 pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n",
959 msr, data);
960 break;
961 }
856 } 962 }
857 return 0; 963 return 0;
858} 964}
@@ -905,26 +1011,47 @@ static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
905 return 0; 1011 return 0;
906} 1012}
907 1013
908int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) 1014static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
909{ 1015{
910 u64 data; 1016 u64 data;
1017 u64 mcg_cap = vcpu->arch.mcg_cap;
1018 unsigned bank_num = mcg_cap & 0xff;
911 1019
912 switch (msr) { 1020 switch (msr) {
913 case 0xc0010010: /* SYSCFG */
914 case 0xc0010015: /* HWCR */
915 case MSR_IA32_PLATFORM_ID:
916 case MSR_IA32_P5_MC_ADDR: 1021 case MSR_IA32_P5_MC_ADDR:
917 case MSR_IA32_P5_MC_TYPE: 1022 case MSR_IA32_P5_MC_TYPE:
918 case MSR_IA32_MC0_CTL: 1023 data = 0;
919 case MSR_IA32_MCG_STATUS: 1024 break;
920 case MSR_IA32_MCG_CAP: 1025 case MSR_IA32_MCG_CAP:
1026 data = vcpu->arch.mcg_cap;
1027 break;
921 case MSR_IA32_MCG_CTL: 1028 case MSR_IA32_MCG_CTL:
922 case MSR_IA32_MC0_MISC: 1029 if (!(mcg_cap & MCG_CTL_P))
923 case MSR_IA32_MC0_MISC+4: 1030 return 1;
924 case MSR_IA32_MC0_MISC+8: 1031 data = vcpu->arch.mcg_ctl;
925 case MSR_IA32_MC0_MISC+12: 1032 break;
926 case MSR_IA32_MC0_MISC+16: 1033 case MSR_IA32_MCG_STATUS:
927 case MSR_IA32_MC0_MISC+20: 1034 data = vcpu->arch.mcg_status;
1035 break;
1036 default:
1037 if (msr >= MSR_IA32_MC0_CTL &&
1038 msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
1039 u32 offset = msr - MSR_IA32_MC0_CTL;
1040 data = vcpu->arch.mce_banks[offset];
1041 break;
1042 }
1043 return 1;
1044 }
1045 *pdata = data;
1046 return 0;
1047}
1048
1049int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
1050{
1051 u64 data;
1052
1053 switch (msr) {
1054 case MSR_IA32_PLATFORM_ID:
928 case MSR_IA32_UCODE_REV: 1055 case MSR_IA32_UCODE_REV:
929 case MSR_IA32_EBL_CR_POWERON: 1056 case MSR_IA32_EBL_CR_POWERON:
930 case MSR_IA32_DEBUGCTLMSR: 1057 case MSR_IA32_DEBUGCTLMSR:
@@ -932,10 +1059,18 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
932 case MSR_IA32_LASTBRANCHTOIP: 1059 case MSR_IA32_LASTBRANCHTOIP:
933 case MSR_IA32_LASTINTFROMIP: 1060 case MSR_IA32_LASTINTFROMIP:
934 case MSR_IA32_LASTINTTOIP: 1061 case MSR_IA32_LASTINTTOIP:
1062 case MSR_K8_SYSCFG:
1063 case MSR_K7_HWCR:
935 case MSR_VM_HSAVE_PA: 1064 case MSR_VM_HSAVE_PA:
1065 case MSR_P6_PERFCTR0:
1066 case MSR_P6_PERFCTR1:
936 case MSR_P6_EVNTSEL0: 1067 case MSR_P6_EVNTSEL0:
937 case MSR_P6_EVNTSEL1: 1068 case MSR_P6_EVNTSEL1:
938 case MSR_K7_EVNTSEL0: 1069 case MSR_K7_EVNTSEL0:
1070 case MSR_K7_PERFCTR0:
1071 case MSR_K8_INT_PENDING_MSG:
1072 case MSR_AMD64_NB_CFG:
1073 case MSR_FAM10H_MMIO_CONF_BASE:
939 data = 0; 1074 data = 0;
940 break; 1075 break;
941 case MSR_MTRRcap: 1076 case MSR_MTRRcap:
@@ -949,6 +1084,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
949 case MSR_IA32_APICBASE: 1084 case MSR_IA32_APICBASE:
950 data = kvm_get_apic_base(vcpu); 1085 data = kvm_get_apic_base(vcpu);
951 break; 1086 break;
1087 case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff:
1088 return kvm_x2apic_msr_read(vcpu, msr, pdata);
1089 break;
952 case MSR_IA32_MISC_ENABLE: 1090 case MSR_IA32_MISC_ENABLE:
953 data = vcpu->arch.ia32_misc_enable_msr; 1091 data = vcpu->arch.ia32_misc_enable_msr;
954 break; 1092 break;
@@ -967,9 +1105,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
967 case MSR_KVM_SYSTEM_TIME: 1105 case MSR_KVM_SYSTEM_TIME:
968 data = vcpu->arch.time; 1106 data = vcpu->arch.time;
969 break; 1107 break;
1108 case MSR_IA32_P5_MC_ADDR:
1109 case MSR_IA32_P5_MC_TYPE:
1110 case MSR_IA32_MCG_CAP:
1111 case MSR_IA32_MCG_CTL:
1112 case MSR_IA32_MCG_STATUS:
1113 case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
1114 return get_msr_mce(vcpu, msr, pdata);
970 default: 1115 default:
971 pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); 1116 if (!ignore_msrs) {
972 return 1; 1117 pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
1118 return 1;
1119 } else {
1120 pr_unimpl(vcpu, "ignored rdmsr: 0x%x\n", msr);
1121 data = 0;
1122 }
1123 break;
973 } 1124 }
974 *pdata = data; 1125 *pdata = data;
975 return 0; 1126 return 0;
@@ -1068,6 +1219,11 @@ int kvm_dev_ioctl_check_extension(long ext)
1068 case KVM_CAP_REINJECT_CONTROL: 1219 case KVM_CAP_REINJECT_CONTROL:
1069 case KVM_CAP_IRQ_INJECT_STATUS: 1220 case KVM_CAP_IRQ_INJECT_STATUS:
1070 case KVM_CAP_ASSIGN_DEV_IRQ: 1221 case KVM_CAP_ASSIGN_DEV_IRQ:
1222 case KVM_CAP_IRQFD:
1223 case KVM_CAP_IOEVENTFD:
1224 case KVM_CAP_PIT2:
1225 case KVM_CAP_PIT_STATE2:
1226 case KVM_CAP_SET_IDENTITY_MAP_ADDR:
1071 r = 1; 1227 r = 1;
1072 break; 1228 break;
1073 case KVM_CAP_COALESCED_MMIO: 1229 case KVM_CAP_COALESCED_MMIO:
@@ -1088,6 +1244,9 @@ int kvm_dev_ioctl_check_extension(long ext)
1088 case KVM_CAP_IOMMU: 1244 case KVM_CAP_IOMMU:
1089 r = iommu_found(); 1245 r = iommu_found();
1090 break; 1246 break;
1247 case KVM_CAP_MCE:
1248 r = KVM_MAX_MCE_BANKS;
1249 break;
1091 default: 1250 default:
1092 r = 0; 1251 r = 0;
1093 break; 1252 break;
@@ -1147,6 +1306,16 @@ long kvm_arch_dev_ioctl(struct file *filp,
1147 r = 0; 1306 r = 0;
1148 break; 1307 break;
1149 } 1308 }
1309 case KVM_X86_GET_MCE_CAP_SUPPORTED: {
1310 u64 mce_cap;
1311
1312 mce_cap = KVM_MCE_CAP_SUPPORTED;
1313 r = -EFAULT;
1314 if (copy_to_user(argp, &mce_cap, sizeof mce_cap))
1315 goto out;
1316 r = 0;
1317 break;
1318 }
1150 default: 1319 default:
1151 r = -EINVAL; 1320 r = -EINVAL;
1152 } 1321 }
@@ -1227,6 +1396,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
1227 vcpu->arch.cpuid_nent = cpuid->nent; 1396 vcpu->arch.cpuid_nent = cpuid->nent;
1228 cpuid_fix_nx_cap(vcpu); 1397 cpuid_fix_nx_cap(vcpu);
1229 r = 0; 1398 r = 0;
1399 kvm_apic_set_version(vcpu);
1230 1400
1231out_free: 1401out_free:
1232 vfree(cpuid_entries); 1402 vfree(cpuid_entries);
@@ -1248,6 +1418,7 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
1248 cpuid->nent * sizeof(struct kvm_cpuid_entry2))) 1418 cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
1249 goto out; 1419 goto out;
1250 vcpu->arch.cpuid_nent = cpuid->nent; 1420 vcpu->arch.cpuid_nent = cpuid->nent;
1421 kvm_apic_set_version(vcpu);
1251 return 0; 1422 return 0;
1252 1423
1253out: 1424out:
@@ -1290,6 +1461,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
1290 u32 index, int *nent, int maxnent) 1461 u32 index, int *nent, int maxnent)
1291{ 1462{
1292 unsigned f_nx = is_efer_nx() ? F(NX) : 0; 1463 unsigned f_nx = is_efer_nx() ? F(NX) : 0;
1464 unsigned f_gbpages = kvm_x86_ops->gb_page_enable() ? F(GBPAGES) : 0;
1293#ifdef CONFIG_X86_64 1465#ifdef CONFIG_X86_64
1294 unsigned f_lm = F(LM); 1466 unsigned f_lm = F(LM);
1295#else 1467#else
@@ -1314,7 +1486,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
1314 F(MTRR) | F(PGE) | F(MCA) | F(CMOV) | 1486 F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
1315 F(PAT) | F(PSE36) | 0 /* Reserved */ | 1487 F(PAT) | F(PSE36) | 0 /* Reserved */ |
1316 f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) | 1488 f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
1317 F(FXSR) | F(FXSR_OPT) | 0 /* GBPAGES */ | 0 /* RDTSCP */ | 1489 F(FXSR) | F(FXSR_OPT) | f_gbpages | 0 /* RDTSCP */ |
1318 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW); 1490 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
1319 /* cpuid 1.ecx */ 1491 /* cpuid 1.ecx */
1320 const u32 kvm_supported_word4_x86_features = 1492 const u32 kvm_supported_word4_x86_features =
@@ -1323,7 +1495,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
1323 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ | 1495 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
1324 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ | 1496 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ |
1325 0 /* Reserved, DCA */ | F(XMM4_1) | 1497 0 /* Reserved, DCA */ | F(XMM4_1) |
1326 F(XMM4_2) | 0 /* x2APIC */ | F(MOVBE) | F(POPCNT) | 1498 F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
1327 0 /* Reserved, XSAVE, OSXSAVE */; 1499 0 /* Reserved, XSAVE, OSXSAVE */;
1328 /* cpuid 0x80000001.ecx */ 1500 /* cpuid 0x80000001.ecx */
1329 const u32 kvm_supported_word6_x86_features = 1501 const u32 kvm_supported_word6_x86_features =
@@ -1344,6 +1516,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
1344 case 1: 1516 case 1:
1345 entry->edx &= kvm_supported_word0_x86_features; 1517 entry->edx &= kvm_supported_word0_x86_features;
1346 entry->ecx &= kvm_supported_word4_x86_features; 1518 entry->ecx &= kvm_supported_word4_x86_features;
1519 /* we support x2apic emulation even if host does not support
1520 * it since we emulate x2apic in software */
1521 entry->ecx |= F(X2APIC);
1347 break; 1522 break;
1348 /* function 2 entries are STATEFUL. That is, repeated cpuid commands 1523 /* function 2 entries are STATEFUL. That is, repeated cpuid commands
1349 * may return different values. This forces us to get_cpu() before 1524 * may return different values. This forces us to get_cpu() before
@@ -1435,6 +1610,10 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
1435 for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func) 1610 for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
1436 do_cpuid_ent(&cpuid_entries[nent], func, 0, 1611 do_cpuid_ent(&cpuid_entries[nent], func, 0,
1437 &nent, cpuid->nent); 1612 &nent, cpuid->nent);
1613 r = -E2BIG;
1614 if (nent >= cpuid->nent)
1615 goto out_free;
1616
1438 r = -EFAULT; 1617 r = -EFAULT;
1439 if (copy_to_user(entries, cpuid_entries, 1618 if (copy_to_user(entries, cpuid_entries,
1440 nent * sizeof(struct kvm_cpuid_entry2))) 1619 nent * sizeof(struct kvm_cpuid_entry2)))
@@ -1464,6 +1643,7 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
1464 vcpu_load(vcpu); 1643 vcpu_load(vcpu);
1465 memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); 1644 memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s);
1466 kvm_apic_post_state_restore(vcpu); 1645 kvm_apic_post_state_restore(vcpu);
1646 update_cr8_intercept(vcpu);
1467 vcpu_put(vcpu); 1647 vcpu_put(vcpu);
1468 1648
1469 return 0; 1649 return 0;
@@ -1503,6 +1683,80 @@ static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu,
1503 return 0; 1683 return 0;
1504} 1684}
1505 1685
1686static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
1687 u64 mcg_cap)
1688{
1689 int r;
1690 unsigned bank_num = mcg_cap & 0xff, bank;
1691
1692 r = -EINVAL;
1693 if (!bank_num)
1694 goto out;
1695 if (mcg_cap & ~(KVM_MCE_CAP_SUPPORTED | 0xff | 0xff0000))
1696 goto out;
1697 r = 0;
1698 vcpu->arch.mcg_cap = mcg_cap;
1699 /* Init IA32_MCG_CTL to all 1s */
1700 if (mcg_cap & MCG_CTL_P)
1701 vcpu->arch.mcg_ctl = ~(u64)0;
1702 /* Init IA32_MCi_CTL to all 1s */
1703 for (bank = 0; bank < bank_num; bank++)
1704 vcpu->arch.mce_banks[bank*4] = ~(u64)0;
1705out:
1706 return r;
1707}
1708
1709static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
1710 struct kvm_x86_mce *mce)
1711{
1712 u64 mcg_cap = vcpu->arch.mcg_cap;
1713 unsigned bank_num = mcg_cap & 0xff;
1714 u64 *banks = vcpu->arch.mce_banks;
1715
1716 if (mce->bank >= bank_num || !(mce->status & MCI_STATUS_VAL))
1717 return -EINVAL;
1718 /*
1719 * if IA32_MCG_CTL is not all 1s, the uncorrected error
1720 * reporting is disabled
1721 */
1722 if ((mce->status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1723 vcpu->arch.mcg_ctl != ~(u64)0)
1724 return 0;
1725 banks += 4 * mce->bank;
1726 /*
1727 * if IA32_MCi_CTL is not all 1s, the uncorrected error
1728 * reporting is disabled for the bank
1729 */
1730 if ((mce->status & MCI_STATUS_UC) && banks[0] != ~(u64)0)
1731 return 0;
1732 if (mce->status & MCI_STATUS_UC) {
1733 if ((vcpu->arch.mcg_status & MCG_STATUS_MCIP) ||
1734 !(vcpu->arch.cr4 & X86_CR4_MCE)) {
1735 printk(KERN_DEBUG "kvm: set_mce: "
1736 "injects mce exception while "
1737 "previous one is in progress!\n");
1738 set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
1739 return 0;
1740 }
1741 if (banks[1] & MCI_STATUS_VAL)
1742 mce->status |= MCI_STATUS_OVER;
1743 banks[2] = mce->addr;
1744 banks[3] = mce->misc;
1745 vcpu->arch.mcg_status = mce->mcg_status;
1746 banks[1] = mce->status;
1747 kvm_queue_exception(vcpu, MC_VECTOR);
1748 } else if (!(banks[1] & MCI_STATUS_VAL)
1749 || !(banks[1] & MCI_STATUS_UC)) {
1750 if (banks[1] & MCI_STATUS_VAL)
1751 mce->status |= MCI_STATUS_OVER;
1752 banks[2] = mce->addr;
1753 banks[3] = mce->misc;
1754 banks[1] = mce->status;
1755 } else
1756 banks[1] |= MCI_STATUS_OVER;
1757 return 0;
1758}
1759
1506long kvm_arch_vcpu_ioctl(struct file *filp, 1760long kvm_arch_vcpu_ioctl(struct file *filp,
1507 unsigned int ioctl, unsigned long arg) 1761 unsigned int ioctl, unsigned long arg)
1508{ 1762{
@@ -1636,6 +1890,24 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
1636 kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); 1890 kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
1637 break; 1891 break;
1638 } 1892 }
1893 case KVM_X86_SETUP_MCE: {
1894 u64 mcg_cap;
1895
1896 r = -EFAULT;
1897 if (copy_from_user(&mcg_cap, argp, sizeof mcg_cap))
1898 goto out;
1899 r = kvm_vcpu_ioctl_x86_setup_mce(vcpu, mcg_cap);
1900 break;
1901 }
1902 case KVM_X86_SET_MCE: {
1903 struct kvm_x86_mce mce;
1904
1905 r = -EFAULT;
1906 if (copy_from_user(&mce, argp, sizeof mce))
1907 goto out;
1908 r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce);
1909 break;
1910 }
1639 default: 1911 default:
1640 r = -EINVAL; 1912 r = -EINVAL;
1641 } 1913 }
@@ -1654,6 +1926,13 @@ static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
1654 return ret; 1926 return ret;
1655} 1927}
1656 1928
1929static int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm,
1930 u64 ident_addr)
1931{
1932 kvm->arch.ept_identity_map_addr = ident_addr;
1933 return 0;
1934}
1935
1657static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, 1936static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
1658 u32 kvm_nr_mmu_pages) 1937 u32 kvm_nr_mmu_pages)
1659{ 1938{
@@ -1775,19 +2054,25 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
1775 r = 0; 2054 r = 0;
1776 switch (chip->chip_id) { 2055 switch (chip->chip_id) {
1777 case KVM_IRQCHIP_PIC_MASTER: 2056 case KVM_IRQCHIP_PIC_MASTER:
2057 spin_lock(&pic_irqchip(kvm)->lock);
1778 memcpy(&pic_irqchip(kvm)->pics[0], 2058 memcpy(&pic_irqchip(kvm)->pics[0],
1779 &chip->chip.pic, 2059 &chip->chip.pic,
1780 sizeof(struct kvm_pic_state)); 2060 sizeof(struct kvm_pic_state));
2061 spin_unlock(&pic_irqchip(kvm)->lock);
1781 break; 2062 break;
1782 case KVM_IRQCHIP_PIC_SLAVE: 2063 case KVM_IRQCHIP_PIC_SLAVE:
2064 spin_lock(&pic_irqchip(kvm)->lock);
1783 memcpy(&pic_irqchip(kvm)->pics[1], 2065 memcpy(&pic_irqchip(kvm)->pics[1],
1784 &chip->chip.pic, 2066 &chip->chip.pic,
1785 sizeof(struct kvm_pic_state)); 2067 sizeof(struct kvm_pic_state));
2068 spin_unlock(&pic_irqchip(kvm)->lock);
1786 break; 2069 break;
1787 case KVM_IRQCHIP_IOAPIC: 2070 case KVM_IRQCHIP_IOAPIC:
2071 mutex_lock(&kvm->irq_lock);
1788 memcpy(ioapic_irqchip(kvm), 2072 memcpy(ioapic_irqchip(kvm),
1789 &chip->chip.ioapic, 2073 &chip->chip.ioapic,
1790 sizeof(struct kvm_ioapic_state)); 2074 sizeof(struct kvm_ioapic_state));
2075 mutex_unlock(&kvm->irq_lock);
1791 break; 2076 break;
1792 default: 2077 default:
1793 r = -EINVAL; 2078 r = -EINVAL;
@@ -1801,7 +2086,9 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
1801{ 2086{
1802 int r = 0; 2087 int r = 0;
1803 2088
2089 mutex_lock(&kvm->arch.vpit->pit_state.lock);
1804 memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state)); 2090 memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state));
2091 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
1805 return r; 2092 return r;
1806} 2093}
1807 2094
@@ -1809,8 +2096,39 @@ static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
1809{ 2096{
1810 int r = 0; 2097 int r = 0;
1811 2098
2099 mutex_lock(&kvm->arch.vpit->pit_state.lock);
1812 memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); 2100 memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
1813 kvm_pit_load_count(kvm, 0, ps->channels[0].count); 2101 kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
2102 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
2103 return r;
2104}
2105
2106static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
2107{
2108 int r = 0;
2109
2110 mutex_lock(&kvm->arch.vpit->pit_state.lock);
2111 memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
2112 sizeof(ps->channels));
2113 ps->flags = kvm->arch.vpit->pit_state.flags;
2114 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
2115 return r;
2116}
2117
2118static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
2119{
2120 int r = 0, start = 0;
2121 u32 prev_legacy, cur_legacy;
2122 mutex_lock(&kvm->arch.vpit->pit_state.lock);
2123 prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
2124 cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY;
2125 if (!prev_legacy && cur_legacy)
2126 start = 1;
2127 memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
2128 sizeof(kvm->arch.vpit->pit_state.channels));
2129 kvm->arch.vpit->pit_state.flags = ps->flags;
2130 kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
2131 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
1814 return r; 2132 return r;
1815} 2133}
1816 2134
@@ -1819,7 +2137,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
1819{ 2137{
1820 if (!kvm->arch.vpit) 2138 if (!kvm->arch.vpit)
1821 return -ENXIO; 2139 return -ENXIO;
2140 mutex_lock(&kvm->arch.vpit->pit_state.lock);
1822 kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject; 2141 kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject;
2142 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
1823 return 0; 2143 return 0;
1824} 2144}
1825 2145
@@ -1845,7 +2165,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
1845 spin_lock(&kvm->mmu_lock); 2165 spin_lock(&kvm->mmu_lock);
1846 kvm_mmu_slot_remove_write_access(kvm, log->slot); 2166 kvm_mmu_slot_remove_write_access(kvm, log->slot);
1847 spin_unlock(&kvm->mmu_lock); 2167 spin_unlock(&kvm->mmu_lock);
1848 kvm_flush_remote_tlbs(kvm);
1849 memslot = &kvm->memslots[log->slot]; 2168 memslot = &kvm->memslots[log->slot];
1850 n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; 2169 n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
1851 memset(memslot->dirty_bitmap, 0, n); 2170 memset(memslot->dirty_bitmap, 0, n);
@@ -1869,7 +2188,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
1869 */ 2188 */
1870 union { 2189 union {
1871 struct kvm_pit_state ps; 2190 struct kvm_pit_state ps;
2191 struct kvm_pit_state2 ps2;
1872 struct kvm_memory_alias alias; 2192 struct kvm_memory_alias alias;
2193 struct kvm_pit_config pit_config;
1873 } u; 2194 } u;
1874 2195
1875 switch (ioctl) { 2196 switch (ioctl) {
@@ -1878,6 +2199,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
1878 if (r < 0) 2199 if (r < 0)
1879 goto out; 2200 goto out;
1880 break; 2201 break;
2202 case KVM_SET_IDENTITY_MAP_ADDR: {
2203 u64 ident_addr;
2204
2205 r = -EFAULT;
2206 if (copy_from_user(&ident_addr, argp, sizeof ident_addr))
2207 goto out;
2208 r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr);
2209 if (r < 0)
2210 goto out;
2211 break;
2212 }
1881 case KVM_SET_MEMORY_REGION: { 2213 case KVM_SET_MEMORY_REGION: {
1882 struct kvm_memory_region kvm_mem; 2214 struct kvm_memory_region kvm_mem;
1883 struct kvm_userspace_memory_region kvm_userspace_mem; 2215 struct kvm_userspace_memory_region kvm_userspace_mem;
@@ -1930,16 +2262,24 @@ long kvm_arch_vm_ioctl(struct file *filp,
1930 } 2262 }
1931 break; 2263 break;
1932 case KVM_CREATE_PIT: 2264 case KVM_CREATE_PIT:
1933 mutex_lock(&kvm->lock); 2265 u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
2266 goto create_pit;
2267 case KVM_CREATE_PIT2:
2268 r = -EFAULT;
2269 if (copy_from_user(&u.pit_config, argp,
2270 sizeof(struct kvm_pit_config)))
2271 goto out;
2272 create_pit:
2273 down_write(&kvm->slots_lock);
1934 r = -EEXIST; 2274 r = -EEXIST;
1935 if (kvm->arch.vpit) 2275 if (kvm->arch.vpit)
1936 goto create_pit_unlock; 2276 goto create_pit_unlock;
1937 r = -ENOMEM; 2277 r = -ENOMEM;
1938 kvm->arch.vpit = kvm_create_pit(kvm); 2278 kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags);
1939 if (kvm->arch.vpit) 2279 if (kvm->arch.vpit)
1940 r = 0; 2280 r = 0;
1941 create_pit_unlock: 2281 create_pit_unlock:
1942 mutex_unlock(&kvm->lock); 2282 up_write(&kvm->slots_lock);
1943 break; 2283 break;
1944 case KVM_IRQ_LINE_STATUS: 2284 case KVM_IRQ_LINE_STATUS:
1945 case KVM_IRQ_LINE: { 2285 case KVM_IRQ_LINE: {
@@ -1950,10 +2290,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
1950 goto out; 2290 goto out;
1951 if (irqchip_in_kernel(kvm)) { 2291 if (irqchip_in_kernel(kvm)) {
1952 __s32 status; 2292 __s32 status;
1953 mutex_lock(&kvm->lock); 2293 mutex_lock(&kvm->irq_lock);
1954 status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 2294 status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
1955 irq_event.irq, irq_event.level); 2295 irq_event.irq, irq_event.level);
1956 mutex_unlock(&kvm->lock); 2296 mutex_unlock(&kvm->irq_lock);
1957 if (ioctl == KVM_IRQ_LINE_STATUS) { 2297 if (ioctl == KVM_IRQ_LINE_STATUS) {
1958 irq_event.status = status; 2298 irq_event.status = status;
1959 if (copy_to_user(argp, &irq_event, 2299 if (copy_to_user(argp, &irq_event,
@@ -2042,6 +2382,32 @@ long kvm_arch_vm_ioctl(struct file *filp,
2042 r = 0; 2382 r = 0;
2043 break; 2383 break;
2044 } 2384 }
2385 case KVM_GET_PIT2: {
2386 r = -ENXIO;
2387 if (!kvm->arch.vpit)
2388 goto out;
2389 r = kvm_vm_ioctl_get_pit2(kvm, &u.ps2);
2390 if (r)
2391 goto out;
2392 r = -EFAULT;
2393 if (copy_to_user(argp, &u.ps2, sizeof(u.ps2)))
2394 goto out;
2395 r = 0;
2396 break;
2397 }
2398 case KVM_SET_PIT2: {
2399 r = -EFAULT;
2400 if (copy_from_user(&u.ps2, argp, sizeof(u.ps2)))
2401 goto out;
2402 r = -ENXIO;
2403 if (!kvm->arch.vpit)
2404 goto out;
2405 r = kvm_vm_ioctl_set_pit2(kvm, &u.ps2);
2406 if (r)
2407 goto out;
2408 r = 0;
2409 break;
2410 }
2045 case KVM_REINJECT_CONTROL: { 2411 case KVM_REINJECT_CONTROL: {
2046 struct kvm_reinject_control control; 2412 struct kvm_reinject_control control;
2047 r = -EFAULT; 2413 r = -EFAULT;
@@ -2075,35 +2441,23 @@ static void kvm_init_msr_list(void)
2075 num_msrs_to_save = j; 2441 num_msrs_to_save = j;
2076} 2442}
2077 2443
2078/* 2444static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
2079 * Only apic need an MMIO device hook, so shortcut now.. 2445 const void *v)
2080 */
2081static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
2082 gpa_t addr, int len,
2083 int is_write)
2084{ 2446{
2085 struct kvm_io_device *dev; 2447 if (vcpu->arch.apic &&
2448 !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v))
2449 return 0;
2086 2450
2087 if (vcpu->arch.apic) { 2451 return kvm_io_bus_write(&vcpu->kvm->mmio_bus, addr, len, v);
2088 dev = &vcpu->arch.apic->dev;
2089 if (dev->in_range(dev, addr, len, is_write))
2090 return dev;
2091 }
2092 return NULL;
2093} 2452}
2094 2453
2095 2454static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
2096static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
2097 gpa_t addr, int len,
2098 int is_write)
2099{ 2455{
2100 struct kvm_io_device *dev; 2456 if (vcpu->arch.apic &&
2457 !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v))
2458 return 0;
2101 2459
2102 dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write); 2460 return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v);
2103 if (dev == NULL)
2104 dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len,
2105 is_write);
2106 return dev;
2107} 2461}
2108 2462
2109static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, 2463static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
@@ -2172,11 +2526,12 @@ static int emulator_read_emulated(unsigned long addr,
2172 unsigned int bytes, 2526 unsigned int bytes,
2173 struct kvm_vcpu *vcpu) 2527 struct kvm_vcpu *vcpu)
2174{ 2528{
2175 struct kvm_io_device *mmio_dev;
2176 gpa_t gpa; 2529 gpa_t gpa;
2177 2530
2178 if (vcpu->mmio_read_completed) { 2531 if (vcpu->mmio_read_completed) {
2179 memcpy(val, vcpu->mmio_data, bytes); 2532 memcpy(val, vcpu->mmio_data, bytes);
2533 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
2534 vcpu->mmio_phys_addr, *(u64 *)val);
2180 vcpu->mmio_read_completed = 0; 2535 vcpu->mmio_read_completed = 0;
2181 return X86EMUL_CONTINUE; 2536 return X86EMUL_CONTINUE;
2182 } 2537 }
@@ -2197,14 +2552,12 @@ mmio:
2197 /* 2552 /*
2198 * Is this MMIO handled locally? 2553 * Is this MMIO handled locally?
2199 */ 2554 */
2200 mutex_lock(&vcpu->kvm->lock); 2555 if (!vcpu_mmio_read(vcpu, gpa, bytes, val)) {
2201 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0); 2556 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, gpa, *(u64 *)val);
2202 if (mmio_dev) {
2203 kvm_iodevice_read(mmio_dev, gpa, bytes, val);
2204 mutex_unlock(&vcpu->kvm->lock);
2205 return X86EMUL_CONTINUE; 2557 return X86EMUL_CONTINUE;
2206 } 2558 }
2207 mutex_unlock(&vcpu->kvm->lock); 2559
2560 trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
2208 2561
2209 vcpu->mmio_needed = 1; 2562 vcpu->mmio_needed = 1;
2210 vcpu->mmio_phys_addr = gpa; 2563 vcpu->mmio_phys_addr = gpa;
@@ -2231,7 +2584,6 @@ static int emulator_write_emulated_onepage(unsigned long addr,
2231 unsigned int bytes, 2584 unsigned int bytes,
2232 struct kvm_vcpu *vcpu) 2585 struct kvm_vcpu *vcpu)
2233{ 2586{
2234 struct kvm_io_device *mmio_dev;
2235 gpa_t gpa; 2587 gpa_t gpa;
2236 2588
2237 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); 2589 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
@@ -2249,17 +2601,12 @@ static int emulator_write_emulated_onepage(unsigned long addr,
2249 return X86EMUL_CONTINUE; 2601 return X86EMUL_CONTINUE;
2250 2602
2251mmio: 2603mmio:
2604 trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
2252 /* 2605 /*
2253 * Is this MMIO handled locally? 2606 * Is this MMIO handled locally?
2254 */ 2607 */
2255 mutex_lock(&vcpu->kvm->lock); 2608 if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
2256 mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1);
2257 if (mmio_dev) {
2258 kvm_iodevice_write(mmio_dev, gpa, bytes, val);
2259 mutex_unlock(&vcpu->kvm->lock);
2260 return X86EMUL_CONTINUE; 2609 return X86EMUL_CONTINUE;
2261 }
2262 mutex_unlock(&vcpu->kvm->lock);
2263 2610
2264 vcpu->mmio_needed = 1; 2611 vcpu->mmio_needed = 1;
2265 vcpu->mmio_phys_addr = gpa; 2612 vcpu->mmio_phys_addr = gpa;
@@ -2297,12 +2644,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
2297 unsigned int bytes, 2644 unsigned int bytes,
2298 struct kvm_vcpu *vcpu) 2645 struct kvm_vcpu *vcpu)
2299{ 2646{
2300 static int reported; 2647 printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
2301
2302 if (!reported) {
2303 reported = 1;
2304 printk(KERN_WARNING "kvm: emulating exchange as write\n");
2305 }
2306#ifndef CONFIG_X86_64 2648#ifndef CONFIG_X86_64
2307 /* guests cmpxchg8b have to be emulated atomically */ 2649 /* guests cmpxchg8b have to be emulated atomically */
2308 if (bytes == 8) { 2650 if (bytes == 8) {
@@ -2348,7 +2690,6 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
2348 2690
2349int emulate_clts(struct kvm_vcpu *vcpu) 2691int emulate_clts(struct kvm_vcpu *vcpu)
2350{ 2692{
2351 KVMTRACE_0D(CLTS, vcpu, handler);
2352 kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS); 2693 kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS);
2353 return X86EMUL_CONTINUE; 2694 return X86EMUL_CONTINUE;
2354} 2695}
@@ -2425,7 +2766,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
2425 kvm_clear_exception_queue(vcpu); 2766 kvm_clear_exception_queue(vcpu);
2426 vcpu->arch.mmio_fault_cr2 = cr2; 2767 vcpu->arch.mmio_fault_cr2 = cr2;
2427 /* 2768 /*
2428 * TODO: fix x86_emulate.c to use guest_read/write_register 2769 * TODO: fix emulate.c to use guest_read/write_register
2429 * instead of direct ->regs accesses, can save hundred cycles 2770 * instead of direct ->regs accesses, can save hundred cycles
2430 * on Intel for instructions that don't read/change RSP, for 2771 * on Intel for instructions that don't read/change RSP, for
2431 * for example. 2772 * for example.
@@ -2449,14 +2790,33 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
2449 2790
2450 r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); 2791 r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
2451 2792
2452 /* Reject the instructions other than VMCALL/VMMCALL when 2793 /* Only allow emulation of specific instructions on #UD
2453 * try to emulate invalid opcode */ 2794 * (namely VMMCALL, sysenter, sysexit, syscall)*/
2454 c = &vcpu->arch.emulate_ctxt.decode; 2795 c = &vcpu->arch.emulate_ctxt.decode;
2455 if ((emulation_type & EMULTYPE_TRAP_UD) && 2796 if (emulation_type & EMULTYPE_TRAP_UD) {
2456 (!(c->twobyte && c->b == 0x01 && 2797 if (!c->twobyte)
2457 (c->modrm_reg == 0 || c->modrm_reg == 3) && 2798 return EMULATE_FAIL;
2458 c->modrm_mod == 3 && c->modrm_rm == 1))) 2799 switch (c->b) {
2459 return EMULATE_FAIL; 2800 case 0x01: /* VMMCALL */
2801 if (c->modrm_mod != 3 || c->modrm_rm != 1)
2802 return EMULATE_FAIL;
2803 break;
2804 case 0x34: /* sysenter */
2805 case 0x35: /* sysexit */
2806 if (c->modrm_mod != 0 || c->modrm_rm != 0)
2807 return EMULATE_FAIL;
2808 break;
2809 case 0x05: /* syscall */
2810 if (c->modrm_mod != 0 || c->modrm_rm != 0)
2811 return EMULATE_FAIL;
2812 break;
2813 default:
2814 return EMULATE_FAIL;
2815 }
2816
2817 if (!(c->modrm_reg == 0 || c->modrm_reg == 3))
2818 return EMULATE_FAIL;
2819 }
2460 2820
2461 ++vcpu->stat.insn_emulation; 2821 ++vcpu->stat.insn_emulation;
2462 if (r) { 2822 if (r) {
@@ -2576,52 +2936,40 @@ int complete_pio(struct kvm_vcpu *vcpu)
2576 return 0; 2936 return 0;
2577} 2937}
2578 2938
2579static void kernel_pio(struct kvm_io_device *pio_dev, 2939static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
2580 struct kvm_vcpu *vcpu,
2581 void *pd)
2582{ 2940{
2583 /* TODO: String I/O for in kernel device */ 2941 /* TODO: String I/O for in kernel device */
2942 int r;
2584 2943
2585 mutex_lock(&vcpu->kvm->lock);
2586 if (vcpu->arch.pio.in) 2944 if (vcpu->arch.pio.in)
2587 kvm_iodevice_read(pio_dev, vcpu->arch.pio.port, 2945 r = kvm_io_bus_read(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
2588 vcpu->arch.pio.size, 2946 vcpu->arch.pio.size, pd);
2589 pd);
2590 else 2947 else
2591 kvm_iodevice_write(pio_dev, vcpu->arch.pio.port, 2948 r = kvm_io_bus_write(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
2592 vcpu->arch.pio.size, 2949 vcpu->arch.pio.size, pd);
2593 pd); 2950 return r;
2594 mutex_unlock(&vcpu->kvm->lock);
2595} 2951}
2596 2952
2597static void pio_string_write(struct kvm_io_device *pio_dev, 2953static int pio_string_write(struct kvm_vcpu *vcpu)
2598 struct kvm_vcpu *vcpu)
2599{ 2954{
2600 struct kvm_pio_request *io = &vcpu->arch.pio; 2955 struct kvm_pio_request *io = &vcpu->arch.pio;
2601 void *pd = vcpu->arch.pio_data; 2956 void *pd = vcpu->arch.pio_data;
2602 int i; 2957 int i, r = 0;
2603 2958
2604 mutex_lock(&vcpu->kvm->lock);
2605 for (i = 0; i < io->cur_count; i++) { 2959 for (i = 0; i < io->cur_count; i++) {
2606 kvm_iodevice_write(pio_dev, io->port, 2960 if (kvm_io_bus_write(&vcpu->kvm->pio_bus,
2607 io->size, 2961 io->port, io->size, pd)) {
2608 pd); 2962 r = -EOPNOTSUPP;
2963 break;
2964 }
2609 pd += io->size; 2965 pd += io->size;
2610 } 2966 }
2611 mutex_unlock(&vcpu->kvm->lock); 2967 return r;
2612}
2613
2614static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
2615 gpa_t addr, int len,
2616 int is_write)
2617{
2618 return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write);
2619} 2968}
2620 2969
2621int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, 2970int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2622 int size, unsigned port) 2971 int size, unsigned port)
2623{ 2972{
2624 struct kvm_io_device *pio_dev;
2625 unsigned long val; 2973 unsigned long val;
2626 2974
2627 vcpu->run->exit_reason = KVM_EXIT_IO; 2975 vcpu->run->exit_reason = KVM_EXIT_IO;
@@ -2635,19 +2983,13 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2635 vcpu->arch.pio.down = 0; 2983 vcpu->arch.pio.down = 0;
2636 vcpu->arch.pio.rep = 0; 2984 vcpu->arch.pio.rep = 0;
2637 2985
2638 if (vcpu->run->io.direction == KVM_EXIT_IO_IN) 2986 trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
2639 KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size, 2987 size, 1);
2640 handler);
2641 else
2642 KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size,
2643 handler);
2644 2988
2645 val = kvm_register_read(vcpu, VCPU_REGS_RAX); 2989 val = kvm_register_read(vcpu, VCPU_REGS_RAX);
2646 memcpy(vcpu->arch.pio_data, &val, 4); 2990 memcpy(vcpu->arch.pio_data, &val, 4);
2647 2991
2648 pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in); 2992 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
2649 if (pio_dev) {
2650 kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
2651 complete_pio(vcpu); 2993 complete_pio(vcpu);
2652 return 1; 2994 return 1;
2653 } 2995 }
@@ -2661,7 +3003,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2661{ 3003{
2662 unsigned now, in_page; 3004 unsigned now, in_page;
2663 int ret = 0; 3005 int ret = 0;
2664 struct kvm_io_device *pio_dev;
2665 3006
2666 vcpu->run->exit_reason = KVM_EXIT_IO; 3007 vcpu->run->exit_reason = KVM_EXIT_IO;
2667 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; 3008 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
@@ -2674,12 +3015,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2674 vcpu->arch.pio.down = down; 3015 vcpu->arch.pio.down = down;
2675 vcpu->arch.pio.rep = rep; 3016 vcpu->arch.pio.rep = rep;
2676 3017
2677 if (vcpu->run->io.direction == KVM_EXIT_IO_IN) 3018 trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
2678 KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size, 3019 size, count);
2679 handler);
2680 else
2681 KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size,
2682 handler);
2683 3020
2684 if (!count) { 3021 if (!count) {
2685 kvm_x86_ops->skip_emulated_instruction(vcpu); 3022 kvm_x86_ops->skip_emulated_instruction(vcpu);
@@ -2709,9 +3046,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2709 3046
2710 vcpu->arch.pio.guest_gva = address; 3047 vcpu->arch.pio.guest_gva = address;
2711 3048
2712 pio_dev = vcpu_find_pio_dev(vcpu, port,
2713 vcpu->arch.pio.cur_count,
2714 !vcpu->arch.pio.in);
2715 if (!vcpu->arch.pio.in) { 3049 if (!vcpu->arch.pio.in) {
2716 /* string PIO write */ 3050 /* string PIO write */
2717 ret = pio_copy_data(vcpu); 3051 ret = pio_copy_data(vcpu);
@@ -2719,16 +3053,13 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
2719 kvm_inject_gp(vcpu, 0); 3053 kvm_inject_gp(vcpu, 0);
2720 return 1; 3054 return 1;
2721 } 3055 }
2722 if (ret == 0 && pio_dev) { 3056 if (ret == 0 && !pio_string_write(vcpu)) {
2723 pio_string_write(pio_dev, vcpu);
2724 complete_pio(vcpu); 3057 complete_pio(vcpu);
2725 if (vcpu->arch.pio.count == 0) 3058 if (vcpu->arch.pio.count == 0)
2726 ret = 1; 3059 ret = 1;
2727 } 3060 }
2728 } else if (pio_dev) 3061 }
2729 pr_unimpl(vcpu, "no string pio read support yet, " 3062 /* no string PIO read support yet */
2730 "port %x size %d count %ld\n",
2731 port, size, count);
2732 3063
2733 return ret; 3064 return ret;
2734} 3065}
@@ -2761,10 +3092,7 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
2761 3092
2762 spin_lock(&kvm_lock); 3093 spin_lock(&kvm_lock);
2763 list_for_each_entry(kvm, &vm_list, vm_list) { 3094 list_for_each_entry(kvm, &vm_list, vm_list) {
2764 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 3095 kvm_for_each_vcpu(i, vcpu, kvm) {
2765 vcpu = kvm->vcpus[i];
2766 if (!vcpu)
2767 continue;
2768 if (vcpu->cpu != freq->cpu) 3096 if (vcpu->cpu != freq->cpu)
2769 continue; 3097 continue;
2770 if (!kvm_request_guest_time_update(vcpu)) 3098 if (!kvm_request_guest_time_update(vcpu))
@@ -2857,7 +3185,6 @@ void kvm_arch_exit(void)
2857int kvm_emulate_halt(struct kvm_vcpu *vcpu) 3185int kvm_emulate_halt(struct kvm_vcpu *vcpu)
2858{ 3186{
2859 ++vcpu->stat.halt_exits; 3187 ++vcpu->stat.halt_exits;
2860 KVMTRACE_0D(HLT, vcpu, handler);
2861 if (irqchip_in_kernel(vcpu->kvm)) { 3188 if (irqchip_in_kernel(vcpu->kvm)) {
2862 vcpu->arch.mp_state = KVM_MP_STATE_HALTED; 3189 vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
2863 return 1; 3190 return 1;
@@ -2888,7 +3215,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
2888 a2 = kvm_register_read(vcpu, VCPU_REGS_RDX); 3215 a2 = kvm_register_read(vcpu, VCPU_REGS_RDX);
2889 a3 = kvm_register_read(vcpu, VCPU_REGS_RSI); 3216 a3 = kvm_register_read(vcpu, VCPU_REGS_RSI);
2890 3217
2891 KVMTRACE_1D(VMMCALL, vcpu, (u32)nr, handler); 3218 trace_kvm_hypercall(nr, a0, a1, a2, a3);
2892 3219
2893 if (!is_long_mode(vcpu)) { 3220 if (!is_long_mode(vcpu)) {
2894 nr &= 0xFFFFFFFF; 3221 nr &= 0xFFFFFFFF;
@@ -2898,6 +3225,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
2898 a3 &= 0xFFFFFFFF; 3225 a3 &= 0xFFFFFFFF;
2899 } 3226 }
2900 3227
3228 if (kvm_x86_ops->get_cpl(vcpu) != 0) {
3229 ret = -KVM_EPERM;
3230 goto out;
3231 }
3232
2901 switch (nr) { 3233 switch (nr) {
2902 case KVM_HC_VAPIC_POLL_IRQ: 3234 case KVM_HC_VAPIC_POLL_IRQ:
2903 ret = 0; 3235 ret = 0;
@@ -2909,6 +3241,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
2909 ret = -KVM_ENOSYS; 3241 ret = -KVM_ENOSYS;
2910 break; 3242 break;
2911 } 3243 }
3244out:
2912 kvm_register_write(vcpu, VCPU_REGS_RAX, ret); 3245 kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
2913 ++vcpu->stat.hypercalls; 3246 ++vcpu->stat.hypercalls;
2914 return r; 3247 return r;
@@ -2988,8 +3321,6 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
2988 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); 3321 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
2989 return 0; 3322 return 0;
2990 } 3323 }
2991 KVMTRACE_3D(CR_READ, vcpu, (u32)cr, (u32)value,
2992 (u32)((u64)value >> 32), handler);
2993 3324
2994 return value; 3325 return value;
2995} 3326}
@@ -2997,9 +3328,6 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
2997void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, 3328void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
2998 unsigned long *rflags) 3329 unsigned long *rflags)
2999{ 3330{
3000 KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, (u32)val,
3001 (u32)((u64)val >> 32), handler);
3002
3003 switch (cr) { 3331 switch (cr) {
3004 case 0: 3332 case 0:
3005 kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val)); 3333 kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val));
@@ -3109,11 +3437,11 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
3109 kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx); 3437 kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx);
3110 } 3438 }
3111 kvm_x86_ops->skip_emulated_instruction(vcpu); 3439 kvm_x86_ops->skip_emulated_instruction(vcpu);
3112 KVMTRACE_5D(CPUID, vcpu, function, 3440 trace_kvm_cpuid(function,
3113 (u32)kvm_register_read(vcpu, VCPU_REGS_RAX), 3441 kvm_register_read(vcpu, VCPU_REGS_RAX),
3114 (u32)kvm_register_read(vcpu, VCPU_REGS_RBX), 3442 kvm_register_read(vcpu, VCPU_REGS_RBX),
3115 (u32)kvm_register_read(vcpu, VCPU_REGS_RCX), 3443 kvm_register_read(vcpu, VCPU_REGS_RCX),
3116 (u32)kvm_register_read(vcpu, VCPU_REGS_RDX), handler); 3444 kvm_register_read(vcpu, VCPU_REGS_RDX));
3117} 3445}
3118EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); 3446EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
3119 3447
@@ -3179,6 +3507,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
3179 if (!kvm_x86_ops->update_cr8_intercept) 3507 if (!kvm_x86_ops->update_cr8_intercept)
3180 return; 3508 return;
3181 3509
3510 if (!vcpu->arch.apic)
3511 return;
3512
3182 if (!vcpu->arch.apic->vapic_addr) 3513 if (!vcpu->arch.apic->vapic_addr)
3183 max_irr = kvm_lapic_find_highest_irr(vcpu); 3514 max_irr = kvm_lapic_find_highest_irr(vcpu);
3184 else 3515 else
@@ -3192,12 +3523,16 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
3192 kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr); 3523 kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr);
3193} 3524}
3194 3525
3195static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 3526static void inject_pending_event(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3196{ 3527{
3197 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
3198 kvm_x86_ops->set_interrupt_shadow(vcpu, 0);
3199
3200 /* try to reinject previous events if any */ 3528 /* try to reinject previous events if any */
3529 if (vcpu->arch.exception.pending) {
3530 kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr,
3531 vcpu->arch.exception.has_error_code,
3532 vcpu->arch.exception.error_code);
3533 return;
3534 }
3535
3201 if (vcpu->arch.nmi_injected) { 3536 if (vcpu->arch.nmi_injected) {
3202 kvm_x86_ops->set_nmi(vcpu); 3537 kvm_x86_ops->set_nmi(vcpu);
3203 return; 3538 return;
@@ -3271,16 +3606,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3271 smp_mb__after_clear_bit(); 3606 smp_mb__after_clear_bit();
3272 3607
3273 if (vcpu->requests || need_resched() || signal_pending(current)) { 3608 if (vcpu->requests || need_resched() || signal_pending(current)) {
3609 set_bit(KVM_REQ_KICK, &vcpu->requests);
3274 local_irq_enable(); 3610 local_irq_enable();
3275 preempt_enable(); 3611 preempt_enable();
3276 r = 1; 3612 r = 1;
3277 goto out; 3613 goto out;
3278 } 3614 }
3279 3615
3280 if (vcpu->arch.exception.pending) 3616 inject_pending_event(vcpu, kvm_run);
3281 __queue_exception(vcpu);
3282 else
3283 inject_pending_irq(vcpu, kvm_run);
3284 3617
3285 /* enable NMI/IRQ window open exits if needed */ 3618 /* enable NMI/IRQ window open exits if needed */
3286 if (vcpu->arch.nmi_pending) 3619 if (vcpu->arch.nmi_pending)
@@ -3297,14 +3630,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3297 3630
3298 kvm_guest_enter(); 3631 kvm_guest_enter();
3299 3632
3300 get_debugreg(vcpu->arch.host_dr6, 6);
3301 get_debugreg(vcpu->arch.host_dr7, 7);
3302 if (unlikely(vcpu->arch.switch_db_regs)) { 3633 if (unlikely(vcpu->arch.switch_db_regs)) {
3303 get_debugreg(vcpu->arch.host_db[0], 0);
3304 get_debugreg(vcpu->arch.host_db[1], 1);
3305 get_debugreg(vcpu->arch.host_db[2], 2);
3306 get_debugreg(vcpu->arch.host_db[3], 3);
3307
3308 set_debugreg(0, 7); 3634 set_debugreg(0, 7);
3309 set_debugreg(vcpu->arch.eff_db[0], 0); 3635 set_debugreg(vcpu->arch.eff_db[0], 0);
3310 set_debugreg(vcpu->arch.eff_db[1], 1); 3636 set_debugreg(vcpu->arch.eff_db[1], 1);
@@ -3312,18 +3638,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3312 set_debugreg(vcpu->arch.eff_db[3], 3); 3638 set_debugreg(vcpu->arch.eff_db[3], 3);
3313 } 3639 }
3314 3640
3315 KVMTRACE_0D(VMENTRY, vcpu, entryexit); 3641 trace_kvm_entry(vcpu->vcpu_id);
3316 kvm_x86_ops->run(vcpu, kvm_run); 3642 kvm_x86_ops->run(vcpu, kvm_run);
3317 3643
3318 if (unlikely(vcpu->arch.switch_db_regs)) { 3644 if (unlikely(vcpu->arch.switch_db_regs || test_thread_flag(TIF_DEBUG))) {
3319 set_debugreg(0, 7); 3645 set_debugreg(current->thread.debugreg[0], 0);
3320 set_debugreg(vcpu->arch.host_db[0], 0); 3646 set_debugreg(current->thread.debugreg[1], 1);
3321 set_debugreg(vcpu->arch.host_db[1], 1); 3647 set_debugreg(current->thread.debugreg[2], 2);
3322 set_debugreg(vcpu->arch.host_db[2], 2); 3648 set_debugreg(current->thread.debugreg[3], 3);
3323 set_debugreg(vcpu->arch.host_db[3], 3); 3649 set_debugreg(current->thread.debugreg6, 6);
3650 set_debugreg(current->thread.debugreg7, 7);
3324 } 3651 }
3325 set_debugreg(vcpu->arch.host_dr6, 6);
3326 set_debugreg(vcpu->arch.host_dr7, 7);
3327 3652
3328 set_bit(KVM_REQ_KICK, &vcpu->requests); 3653 set_bit(KVM_REQ_KICK, &vcpu->requests);
3329 local_irq_enable(); 3654 local_irq_enable();
@@ -3653,11 +3978,8 @@ static void kvm_set_segment(struct kvm_vcpu *vcpu,
3653static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, 3978static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector,
3654 struct kvm_segment *kvm_desct) 3979 struct kvm_segment *kvm_desct)
3655{ 3980{
3656 kvm_desct->base = seg_desc->base0; 3981 kvm_desct->base = get_desc_base(seg_desc);
3657 kvm_desct->base |= seg_desc->base1 << 16; 3982 kvm_desct->limit = get_desc_limit(seg_desc);
3658 kvm_desct->base |= seg_desc->base2 << 24;
3659 kvm_desct->limit = seg_desc->limit0;
3660 kvm_desct->limit |= seg_desc->limit << 16;
3661 if (seg_desc->g) { 3983 if (seg_desc->g) {
3662 kvm_desct->limit <<= 12; 3984 kvm_desct->limit <<= 12;
3663 kvm_desct->limit |= 0xfff; 3985 kvm_desct->limit |= 0xfff;
@@ -3701,7 +4023,6 @@ static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu,
3701static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, 4023static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3702 struct desc_struct *seg_desc) 4024 struct desc_struct *seg_desc)
3703{ 4025{
3704 gpa_t gpa;
3705 struct descriptor_table dtable; 4026 struct descriptor_table dtable;
3706 u16 index = selector >> 3; 4027 u16 index = selector >> 3;
3707 4028
@@ -3711,16 +4032,13 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3711 kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); 4032 kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
3712 return 1; 4033 return 1;
3713 } 4034 }
3714 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); 4035 return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
3715 gpa += index * 8;
3716 return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8);
3717} 4036}
3718 4037
3719/* allowed just for 8 bytes segments */ 4038/* allowed just for 8 bytes segments */
3720static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, 4039static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3721 struct desc_struct *seg_desc) 4040 struct desc_struct *seg_desc)
3722{ 4041{
3723 gpa_t gpa;
3724 struct descriptor_table dtable; 4042 struct descriptor_table dtable;
3725 u16 index = selector >> 3; 4043 u16 index = selector >> 3;
3726 4044
@@ -3728,19 +4046,13 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3728 4046
3729 if (dtable.limit < index * 8 + 7) 4047 if (dtable.limit < index * 8 + 7)
3730 return 1; 4048 return 1;
3731 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); 4049 return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
3732 gpa += index * 8;
3733 return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8);
3734} 4050}
3735 4051
3736static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, 4052static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
3737 struct desc_struct *seg_desc) 4053 struct desc_struct *seg_desc)
3738{ 4054{
3739 u32 base_addr; 4055 u32 base_addr = get_desc_base(seg_desc);
3740
3741 base_addr = seg_desc->base0;
3742 base_addr |= (seg_desc->base1 << 16);
3743 base_addr |= (seg_desc->base2 << 24);
3744 4056
3745 return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr); 4057 return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
3746} 4058}
@@ -3785,12 +4097,19 @@ static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int se
3785 return 0; 4097 return 0;
3786} 4098}
3787 4099
4100static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg)
4101{
4102 return (seg != VCPU_SREG_LDTR) &&
4103 (seg != VCPU_SREG_TR) &&
4104 (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_VM);
4105}
4106
3788int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, 4107int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
3789 int type_bits, int seg) 4108 int type_bits, int seg)
3790{ 4109{
3791 struct kvm_segment kvm_seg; 4110 struct kvm_segment kvm_seg;
3792 4111
3793 if (!(vcpu->arch.cr0 & X86_CR0_PE)) 4112 if (is_vm86_segment(vcpu, seg) || !(vcpu->arch.cr0 & X86_CR0_PE))
3794 return kvm_load_realmode_segment(vcpu, selector, seg); 4113 return kvm_load_realmode_segment(vcpu, selector, seg);
3795 if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) 4114 if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
3796 return 1; 4115 return 1;
@@ -4029,7 +4348,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
4029 } 4348 }
4030 } 4349 }
4031 4350
4032 if (!nseg_desc.p || (nseg_desc.limit0 | nseg_desc.limit << 16) < 0x67) { 4351 if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
4033 kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc); 4352 kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
4034 return 1; 4353 return 1;
4035 } 4354 }
@@ -4099,13 +4418,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
4099 4418
4100 vcpu->arch.cr2 = sregs->cr2; 4419 vcpu->arch.cr2 = sregs->cr2;
4101 mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3; 4420 mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3;
4102 4421 vcpu->arch.cr3 = sregs->cr3;
4103 down_read(&vcpu->kvm->slots_lock);
4104 if (gfn_to_memslot(vcpu->kvm, sregs->cr3 >> PAGE_SHIFT))
4105 vcpu->arch.cr3 = sregs->cr3;
4106 else
4107 set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
4108 up_read(&vcpu->kvm->slots_lock);
4109 4422
4110 kvm_set_cr8(vcpu, sregs->cr8); 4423 kvm_set_cr8(vcpu, sregs->cr8);
4111 4424
@@ -4147,8 +4460,10 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
4147 kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); 4460 kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
4148 kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); 4461 kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
4149 4462
4463 update_cr8_intercept(vcpu);
4464
4150 /* Older userspace won't unhalt the vcpu on reset. */ 4465 /* Older userspace won't unhalt the vcpu on reset. */
4151 if (vcpu->vcpu_id == 0 && kvm_rip_read(vcpu) == 0xfff0 && 4466 if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
4152 sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 && 4467 sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
4153 !(vcpu->arch.cr0 & X86_CR0_PE)) 4468 !(vcpu->arch.cr0 & X86_CR0_PE))
4154 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; 4469 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
@@ -4419,7 +4734,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
4419 kvm = vcpu->kvm; 4734 kvm = vcpu->kvm;
4420 4735
4421 vcpu->arch.mmu.root_hpa = INVALID_PAGE; 4736 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
4422 if (!irqchip_in_kernel(kvm) || vcpu->vcpu_id == 0) 4737 if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu))
4423 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; 4738 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
4424 else 4739 else
4425 vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; 4740 vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED;
@@ -4441,6 +4756,14 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
4441 goto fail_mmu_destroy; 4756 goto fail_mmu_destroy;
4442 } 4757 }
4443 4758
4759 vcpu->arch.mce_banks = kzalloc(KVM_MAX_MCE_BANKS * sizeof(u64) * 4,
4760 GFP_KERNEL);
4761 if (!vcpu->arch.mce_banks) {
4762 r = -ENOMEM;
4763 goto fail_mmu_destroy;
4764 }
4765 vcpu->arch.mcg_cap = KVM_MAX_MCE_BANKS;
4766
4444 return 0; 4767 return 0;
4445 4768
4446fail_mmu_destroy: 4769fail_mmu_destroy:
@@ -4488,20 +4811,22 @@ static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
4488static void kvm_free_vcpus(struct kvm *kvm) 4811static void kvm_free_vcpus(struct kvm *kvm)
4489{ 4812{
4490 unsigned int i; 4813 unsigned int i;
4814 struct kvm_vcpu *vcpu;
4491 4815
4492 /* 4816 /*
4493 * Unpin any mmu pages first. 4817 * Unpin any mmu pages first.
4494 */ 4818 */
4495 for (i = 0; i < KVM_MAX_VCPUS; ++i) 4819 kvm_for_each_vcpu(i, vcpu, kvm)
4496 if (kvm->vcpus[i]) 4820 kvm_unload_vcpu_mmu(vcpu);
4497 kvm_unload_vcpu_mmu(kvm->vcpus[i]); 4821 kvm_for_each_vcpu(i, vcpu, kvm)
4498 for (i = 0; i < KVM_MAX_VCPUS; ++i) { 4822 kvm_arch_vcpu_free(vcpu);
4499 if (kvm->vcpus[i]) { 4823
4500 kvm_arch_vcpu_free(kvm->vcpus[i]); 4824 mutex_lock(&kvm->lock);
4501 kvm->vcpus[i] = NULL; 4825 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
4502 } 4826 kvm->vcpus[i] = NULL;
4503 }
4504 4827
4828 atomic_set(&kvm->online_vcpus, 0);
4829 mutex_unlock(&kvm->lock);
4505} 4830}
4506 4831
4507void kvm_arch_sync_events(struct kvm *kvm) 4832void kvm_arch_sync_events(struct kvm *kvm)
@@ -4578,7 +4903,6 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
4578 4903
4579 kvm_mmu_slot_remove_write_access(kvm, mem->slot); 4904 kvm_mmu_slot_remove_write_access(kvm, mem->slot);
4580 spin_unlock(&kvm->mmu_lock); 4905 spin_unlock(&kvm->mmu_lock);
4581 kvm_flush_remote_tlbs(kvm);
4582 4906
4583 return 0; 4907 return 0;
4584} 4908}
@@ -4592,8 +4916,10 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
4592int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) 4916int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
4593{ 4917{
4594 return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE 4918 return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE
4595 || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED 4919 || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED
4596 || vcpu->arch.nmi_pending; 4920 || vcpu->arch.nmi_pending ||
4921 (kvm_arch_interrupt_allowed(vcpu) &&
4922 kvm_cpu_has_interrupt(vcpu));
4597} 4923}
4598 4924
4599void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 4925void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
@@ -4617,3 +4943,9 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
4617{ 4943{
4618 return kvm_x86_ops->interrupt_allowed(vcpu); 4944 return kvm_x86_ops->interrupt_allowed(vcpu);
4619} 4945}
4946
4947EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
4948EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
4949EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);
4950EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_msr);
4951EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_cr);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 4c8e10af78e8..5eadea585d2a 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -31,4 +31,8 @@ static inline bool kvm_exception_is_soft(unsigned int nr)
31{ 31{
32 return (nr == BP_VECTOR) || (nr == OF_VECTOR); 32 return (nr == BP_VECTOR) || (nr == OF_VECTOR);
33} 33}
34
35struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
36 u32 function, u32 index);
37
34#endif 38#endif
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 07c31899c9c2..9e609206fac9 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -9,6 +9,8 @@ lib-y += thunk_$(BITS).o
9lib-y += usercopy_$(BITS).o getuser.o putuser.o 9lib-y += usercopy_$(BITS).o getuser.o putuser.o
10lib-y += memcpy_$(BITS).o 10lib-y += memcpy_$(BITS).o
11 11
12obj-y += msr-reg.o msr-reg-export.o
13
12ifeq ($(CONFIG_X86_32),y) 14ifeq ($(CONFIG_X86_32),y)
13 obj-y += atomic64_32.o 15 obj-y += atomic64_32.o
14 lib-y += checksum_32.o 16 lib-y += checksum_32.o
diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c
new file mode 100644
index 000000000000..a311cc59b65d
--- /dev/null
+++ b/arch/x86/lib/msr-reg-export.c
@@ -0,0 +1,5 @@
1#include <linux/module.h>
2#include <asm/msr.h>
3
4EXPORT_SYMBOL(native_rdmsr_safe_regs);
5EXPORT_SYMBOL(native_wrmsr_safe_regs);
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
new file mode 100644
index 000000000000..69fa10623f21
--- /dev/null
+++ b/arch/x86/lib/msr-reg.S
@@ -0,0 +1,102 @@
1#include <linux/linkage.h>
2#include <linux/errno.h>
3#include <asm/dwarf2.h>
4#include <asm/asm.h>
5#include <asm/msr.h>
6
7#ifdef CONFIG_X86_64
8/*
9 * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]);
10 *
11 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi]
12 *
13 */
14.macro op_safe_regs op
15ENTRY(native_\op\()_safe_regs)
16 CFI_STARTPROC
17 pushq_cfi %rbx
18 pushq_cfi %rbp
19 movq %rdi, %r10 /* Save pointer */
20 xorl %r11d, %r11d /* Return value */
21 movl (%rdi), %eax
22 movl 4(%rdi), %ecx
23 movl 8(%rdi), %edx
24 movl 12(%rdi), %ebx
25 movl 20(%rdi), %ebp
26 movl 24(%rdi), %esi
27 movl 28(%rdi), %edi
28 CFI_REMEMBER_STATE
291: \op
302: movl %eax, (%r10)
31 movl %r11d, %eax /* Return value */
32 movl %ecx, 4(%r10)
33 movl %edx, 8(%r10)
34 movl %ebx, 12(%r10)
35 movl %ebp, 20(%r10)
36 movl %esi, 24(%r10)
37 movl %edi, 28(%r10)
38 popq_cfi %rbp
39 popq_cfi %rbx
40 ret
413:
42 CFI_RESTORE_STATE
43 movl $-EIO, %r11d
44 jmp 2b
45
46 _ASM_EXTABLE(1b, 3b)
47 CFI_ENDPROC
48ENDPROC(native_\op\()_safe_regs)
49.endm
50
51#else /* X86_32 */
52
53.macro op_safe_regs op
54ENTRY(native_\op\()_safe_regs)
55 CFI_STARTPROC
56 pushl_cfi %ebx
57 pushl_cfi %ebp
58 pushl_cfi %esi
59 pushl_cfi %edi
60 pushl_cfi $0 /* Return value */
61 pushl_cfi %eax
62 movl 4(%eax), %ecx
63 movl 8(%eax), %edx
64 movl 12(%eax), %ebx
65 movl 20(%eax), %ebp
66 movl 24(%eax), %esi
67 movl 28(%eax), %edi
68 movl (%eax), %eax
69 CFI_REMEMBER_STATE
701: \op
712: pushl_cfi %eax
72 movl 4(%esp), %eax
73 popl_cfi (%eax)
74 addl $4, %esp
75 CFI_ADJUST_CFA_OFFSET -4
76 movl %ecx, 4(%eax)
77 movl %edx, 8(%eax)
78 movl %ebx, 12(%eax)
79 movl %ebp, 20(%eax)
80 movl %esi, 24(%eax)
81 movl %edi, 28(%eax)
82 popl_cfi %eax
83 popl_cfi %edi
84 popl_cfi %esi
85 popl_cfi %ebp
86 popl_cfi %ebx
87 ret
883:
89 CFI_RESTORE_STATE
90 movl $-EIO, 4(%esp)
91 jmp 2b
92
93 _ASM_EXTABLE(1b, 3b)
94 CFI_ENDPROC
95ENDPROC(native_\op\()_safe_regs)
96.endm
97
98#endif
99
100op_safe_regs rdmsr
101op_safe_regs wrmsr
102
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index caa24aca8115..33a1e3ca22d8 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -175,3 +175,52 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
175 return err ? err : rv.err; 175 return err ? err : rv.err;
176} 176}
177EXPORT_SYMBOL(wrmsr_safe_on_cpu); 177EXPORT_SYMBOL(wrmsr_safe_on_cpu);
178
179/*
180 * These variants are significantly slower, but allows control over
181 * the entire 32-bit GPR set.
182 */
183struct msr_regs_info {
184 u32 *regs;
185 int err;
186};
187
188static void __rdmsr_safe_regs_on_cpu(void *info)
189{
190 struct msr_regs_info *rv = info;
191
192 rv->err = rdmsr_safe_regs(rv->regs);
193}
194
195static void __wrmsr_safe_regs_on_cpu(void *info)
196{
197 struct msr_regs_info *rv = info;
198
199 rv->err = wrmsr_safe_regs(rv->regs);
200}
201
202int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
203{
204 int err;
205 struct msr_regs_info rv;
206
207 rv.regs = regs;
208 rv.err = -EIO;
209 err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
210
211 return err ? err : rv.err;
212}
213EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
214
215int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
216{
217 int err;
218 struct msr_regs_info rv;
219
220 rv.regs = regs;
221 rv.err = -EIO;
222 err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
223
224 return err ? err : rv.err;
225}
226EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index eefdeee8a871..9b5a9f59a478 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -1,5 +1,9 @@
1obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ 1obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
2 pat.o pgtable.o gup.o 2 pat.o pgtable.o physaddr.o gup.o
3
4# Make sure __phys_addr has no stackprotector
5nostackp := $(call cc-option, -fno-stack-protector)
6CFLAGS_physaddr.o := $(nostackp)
3 7
4obj-$(CONFIG_SMP) += tlb.o 8obj-$(CONFIG_SMP) += tlb.o
5 9
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index bfae139182ff..775a020990a5 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -285,26 +285,25 @@ check_v8086_mode(struct pt_regs *regs, unsigned long address,
285 tsk->thread.screen_bitmap |= 1 << bit; 285 tsk->thread.screen_bitmap |= 1 << bit;
286} 286}
287 287
288static void dump_pagetable(unsigned long address) 288static bool low_pfn(unsigned long pfn)
289{ 289{
290 __typeof__(pte_val(__pte(0))) page; 290 return pfn < max_low_pfn;
291}
291 292
292 page = read_cr3(); 293static void dump_pagetable(unsigned long address)
293 page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT]; 294{
295 pgd_t *base = __va(read_cr3());
296 pgd_t *pgd = &base[pgd_index(address)];
297 pmd_t *pmd;
298 pte_t *pte;
294 299
295#ifdef CONFIG_X86_PAE 300#ifdef CONFIG_X86_PAE
296 printk("*pdpt = %016Lx ", page); 301 printk("*pdpt = %016Lx ", pgd_val(*pgd));
297 if ((page >> PAGE_SHIFT) < max_low_pfn 302 if (!low_pfn(pgd_val(*pgd) >> PAGE_SHIFT) || !pgd_present(*pgd))
298 && page & _PAGE_PRESENT) { 303 goto out;
299 page &= PAGE_MASK;
300 page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
301 & (PTRS_PER_PMD - 1)];
302 printk(KERN_CONT "*pde = %016Lx ", page);
303 page &= ~_PAGE_NX;
304 }
305#else
306 printk("*pde = %08lx ", page);
307#endif 304#endif
305 pmd = pmd_offset(pud_offset(pgd, address), address);
306 printk(KERN_CONT "*pde = %0*Lx ", sizeof(*pmd) * 2, (u64)pmd_val(*pmd));
308 307
309 /* 308 /*
310 * We must not directly access the pte in the highpte 309 * We must not directly access the pte in the highpte
@@ -312,16 +311,12 @@ static void dump_pagetable(unsigned long address)
312 * And let's rather not kmap-atomic the pte, just in case 311 * And let's rather not kmap-atomic the pte, just in case
313 * it's allocated already: 312 * it's allocated already:
314 */ 313 */
315 if ((page >> PAGE_SHIFT) < max_low_pfn 314 if (!low_pfn(pmd_pfn(*pmd)) || !pmd_present(*pmd) || pmd_large(*pmd))
316 && (page & _PAGE_PRESENT) 315 goto out;
317 && !(page & _PAGE_PSE)) {
318
319 page &= PAGE_MASK;
320 page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
321 & (PTRS_PER_PTE - 1)];
322 printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
323 }
324 316
317 pte = pte_offset_kernel(pmd, address);
318 printk("*pte = %0*Lx ", sizeof(*pte) * 2, (u64)pte_val(*pte));
319out:
325 printk("\n"); 320 printk("\n");
326} 321}
327 322
@@ -450,16 +445,12 @@ static int bad_address(void *p)
450 445
451static void dump_pagetable(unsigned long address) 446static void dump_pagetable(unsigned long address)
452{ 447{
453 pgd_t *pgd; 448 pgd_t *base = __va(read_cr3() & PHYSICAL_PAGE_MASK);
449 pgd_t *pgd = base + pgd_index(address);
454 pud_t *pud; 450 pud_t *pud;
455 pmd_t *pmd; 451 pmd_t *pmd;
456 pte_t *pte; 452 pte_t *pte;
457 453
458 pgd = (pgd_t *)read_cr3();
459
460 pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
461
462 pgd += pgd_index(address);
463 if (bad_address(pgd)) 454 if (bad_address(pgd))
464 goto bad; 455 goto bad;
465 456
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 2112ed55e7ea..63a6ba66cbe0 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -24,7 +24,7 @@ void kunmap(struct page *page)
24 * no global lock is needed and because the kmap code must perform a global TLB 24 * no global lock is needed and because the kmap code must perform a global TLB
25 * invalidation when the kmap pool wraps. 25 * invalidation when the kmap pool wraps.
26 * 26 *
27 * However when holding an atomic kmap is is not legal to sleep, so atomic 27 * However when holding an atomic kmap it is not legal to sleep, so atomic
28 * kmaps are appropriate for short, tight code paths only. 28 * kmaps are appropriate for short, tight code paths only.
29 */ 29 */
30void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) 30void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
@@ -104,6 +104,7 @@ EXPORT_SYMBOL(kunmap);
104EXPORT_SYMBOL(kmap_atomic); 104EXPORT_SYMBOL(kmap_atomic);
105EXPORT_SYMBOL(kunmap_atomic); 105EXPORT_SYMBOL(kunmap_atomic);
106EXPORT_SYMBOL(kmap_atomic_prot); 106EXPORT_SYMBOL(kmap_atomic_prot);
107EXPORT_SYMBOL(kmap_atomic_to_page);
107 108
108void __init set_highmem_pages_init(void) 109void __init set_highmem_pages_init(void)
109{ 110{
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 8a450930834f..04e1ad60c63a 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -22,77 +22,7 @@
22#include <asm/pgalloc.h> 22#include <asm/pgalloc.h>
23#include <asm/pat.h> 23#include <asm/pat.h>
24 24
25static inline int phys_addr_valid(resource_size_t addr) 25#include "physaddr.h"
26{
27#ifdef CONFIG_PHYS_ADDR_T_64BIT
28 return !(addr >> boot_cpu_data.x86_phys_bits);
29#else
30 return 1;
31#endif
32}
33
34#ifdef CONFIG_X86_64
35
36unsigned long __phys_addr(unsigned long x)
37{
38 if (x >= __START_KERNEL_map) {
39 x -= __START_KERNEL_map;
40 VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
41 x += phys_base;
42 } else {
43 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
44 x -= PAGE_OFFSET;
45 VIRTUAL_BUG_ON(!phys_addr_valid(x));
46 }
47 return x;
48}
49EXPORT_SYMBOL(__phys_addr);
50
51bool __virt_addr_valid(unsigned long x)
52{
53 if (x >= __START_KERNEL_map) {
54 x -= __START_KERNEL_map;
55 if (x >= KERNEL_IMAGE_SIZE)
56 return false;
57 x += phys_base;
58 } else {
59 if (x < PAGE_OFFSET)
60 return false;
61 x -= PAGE_OFFSET;
62 if (!phys_addr_valid(x))
63 return false;
64 }
65
66 return pfn_valid(x >> PAGE_SHIFT);
67}
68EXPORT_SYMBOL(__virt_addr_valid);
69
70#else
71
72#ifdef CONFIG_DEBUG_VIRTUAL
73unsigned long __phys_addr(unsigned long x)
74{
75 /* VMALLOC_* aren't constants */
76 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
77 VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
78 return x - PAGE_OFFSET;
79}
80EXPORT_SYMBOL(__phys_addr);
81#endif
82
83bool __virt_addr_valid(unsigned long x)
84{
85 if (x < PAGE_OFFSET)
86 return false;
87 if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
88 return false;
89 if (x >= FIXADDR_START)
90 return false;
91 return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
92}
93EXPORT_SYMBOL(__virt_addr_valid);
94
95#endif
96 26
97int page_is_ram(unsigned long pagenr) 27int page_is_ram(unsigned long pagenr)
98{ 28{
diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c
index 2c55ed098654..528bf954eb74 100644
--- a/arch/x86/mm/kmemcheck/kmemcheck.c
+++ b/arch/x86/mm/kmemcheck/kmemcheck.c
@@ -331,6 +331,20 @@ static void kmemcheck_read_strict(struct pt_regs *regs,
331 kmemcheck_shadow_set(shadow, size); 331 kmemcheck_shadow_set(shadow, size);
332} 332}
333 333
334bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size)
335{
336 enum kmemcheck_shadow status;
337 void *shadow;
338
339 shadow = kmemcheck_shadow_lookup(addr);
340 if (!shadow)
341 return true;
342
343 status = kmemcheck_shadow_test(shadow, size);
344
345 return status == KMEMCHECK_SHADOW_INITIALIZED;
346}
347
334/* Access may cross page boundary */ 348/* Access may cross page boundary */
335static void kmemcheck_read(struct pt_regs *regs, 349static void kmemcheck_read(struct pt_regs *regs,
336 unsigned long addr, unsigned int size) 350 unsigned long addr, unsigned int size)
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 352aa9e927e2..b2f7d3e59b86 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -827,7 +827,7 @@ static int memtype_seq_show(struct seq_file *seq, void *v)
827 return 0; 827 return 0;
828} 828}
829 829
830static struct seq_operations memtype_seq_ops = { 830static const struct seq_operations memtype_seq_ops = {
831 .start = memtype_seq_start, 831 .start = memtype_seq_start,
832 .next = memtype_seq_next, 832 .next = memtype_seq_next,
833 .stop = memtype_seq_stop, 833 .stop = memtype_seq_stop,
diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c
new file mode 100644
index 000000000000..d2e2735327b4
--- /dev/null
+++ b/arch/x86/mm/physaddr.c
@@ -0,0 +1,70 @@
1#include <linux/mmdebug.h>
2#include <linux/module.h>
3#include <linux/mm.h>
4
5#include <asm/page.h>
6
7#include "physaddr.h"
8
9#ifdef CONFIG_X86_64
10
11unsigned long __phys_addr(unsigned long x)
12{
13 if (x >= __START_KERNEL_map) {
14 x -= __START_KERNEL_map;
15 VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
16 x += phys_base;
17 } else {
18 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
19 x -= PAGE_OFFSET;
20 VIRTUAL_BUG_ON(!phys_addr_valid(x));
21 }
22 return x;
23}
24EXPORT_SYMBOL(__phys_addr);
25
26bool __virt_addr_valid(unsigned long x)
27{
28 if (x >= __START_KERNEL_map) {
29 x -= __START_KERNEL_map;
30 if (x >= KERNEL_IMAGE_SIZE)
31 return false;
32 x += phys_base;
33 } else {
34 if (x < PAGE_OFFSET)
35 return false;
36 x -= PAGE_OFFSET;
37 if (!phys_addr_valid(x))
38 return false;
39 }
40
41 return pfn_valid(x >> PAGE_SHIFT);
42}
43EXPORT_SYMBOL(__virt_addr_valid);
44
45#else
46
47#ifdef CONFIG_DEBUG_VIRTUAL
48unsigned long __phys_addr(unsigned long x)
49{
50 /* VMALLOC_* aren't constants */
51 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
52 VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
53 return x - PAGE_OFFSET;
54}
55EXPORT_SYMBOL(__phys_addr);
56#endif
57
58bool __virt_addr_valid(unsigned long x)
59{
60 if (x < PAGE_OFFSET)
61 return false;
62 if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
63 return false;
64 if (x >= FIXADDR_START)
65 return false;
66 return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
67}
68EXPORT_SYMBOL(__virt_addr_valid);
69
70#endif /* CONFIG_X86_64 */
diff --git a/arch/x86/mm/physaddr.h b/arch/x86/mm/physaddr.h
new file mode 100644
index 000000000000..a3cd5a0c97b3
--- /dev/null
+++ b/arch/x86/mm/physaddr.h
@@ -0,0 +1,10 @@
1#include <asm/processor.h>
2
3static inline int phys_addr_valid(resource_size_t addr)
4{
5#ifdef CONFIG_PHYS_ADDR_T_64BIT
6 return !(addr >> boot_cpu_data.x86_phys_bits);
7#else
8 return 1;
9#endif
10}
diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c
index 29a0e37114f8..6f8aa33031c7 100644
--- a/arch/x86/mm/srat_32.c
+++ b/arch/x86/mm/srat_32.c
@@ -215,7 +215,7 @@ int __init get_memcfg_from_srat(void)
215 goto out_fail; 215 goto out_fail;
216 216
217 if (num_memory_chunks == 0) { 217 if (num_memory_chunks == 0) {
218 printk(KERN_WARNING 218 printk(KERN_DEBUG
219 "could not find any ACPI SRAT memory areas.\n"); 219 "could not find any ACPI SRAT memory areas.\n");
220 goto out_fail; 220 goto out_fail;
221 } 221 }
@@ -277,7 +277,7 @@ int __init get_memcfg_from_srat(void)
277 } 277 }
278 return 1; 278 return 1;
279out_fail: 279out_fail:
280 printk(KERN_ERR "failed to get NUMA memory information from SRAT" 280 printk(KERN_DEBUG "failed to get NUMA memory information from SRAT"
281 " table\n"); 281 " table\n");
282 return 0; 282 return 0;
283} 283}
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 89b9a5cd63da..cb88b1a0bd5f 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -1,11 +1,14 @@
1/** 1/**
2 * @file nmi_int.c 2 * @file nmi_int.c
3 * 3 *
4 * @remark Copyright 2002-2008 OProfile authors 4 * @remark Copyright 2002-2009 OProfile authors
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author John Levon <levon@movementarian.org> 7 * @author John Levon <levon@movementarian.org>
8 * @author Robert Richter <robert.richter@amd.com> 8 * @author Robert Richter <robert.richter@amd.com>
9 * @author Barry Kasindorf <barry.kasindorf@amd.com>
10 * @author Jason Yeh <jason.yeh@amd.com>
11 * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
9 */ 12 */
10 13
11#include <linux/init.h> 14#include <linux/init.h>
@@ -24,13 +27,35 @@
24#include "op_counter.h" 27#include "op_counter.h"
25#include "op_x86_model.h" 28#include "op_x86_model.h"
26 29
27static struct op_x86_model_spec const *model; 30static struct op_x86_model_spec *model;
28static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); 31static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
29static DEFINE_PER_CPU(unsigned long, saved_lvtpc); 32static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
30 33
31/* 0 == registered but off, 1 == registered and on */ 34/* 0 == registered but off, 1 == registered and on */
32static int nmi_enabled = 0; 35static int nmi_enabled = 0;
33 36
37struct op_counter_config counter_config[OP_MAX_COUNTER];
38
39/* common functions */
40
41u64 op_x86_get_ctrl(struct op_x86_model_spec const *model,
42 struct op_counter_config *counter_config)
43{
44 u64 val = 0;
45 u16 event = (u16)counter_config->event;
46
47 val |= ARCH_PERFMON_EVENTSEL_INT;
48 val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0;
49 val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0;
50 val |= (counter_config->unit_mask & 0xFF) << 8;
51 event &= model->event_mask ? model->event_mask : 0xFF;
52 val |= event & 0xFF;
53 val |= (event & 0x0F00) << 24;
54
55 return val;
56}
57
58
34static int profile_exceptions_notify(struct notifier_block *self, 59static int profile_exceptions_notify(struct notifier_block *self,
35 unsigned long val, void *data) 60 unsigned long val, void *data)
36{ 61{
@@ -52,36 +77,214 @@ static int profile_exceptions_notify(struct notifier_block *self,
52 77
53static void nmi_cpu_save_registers(struct op_msrs *msrs) 78static void nmi_cpu_save_registers(struct op_msrs *msrs)
54{ 79{
55 unsigned int const nr_ctrs = model->num_counters;
56 unsigned int const nr_ctrls = model->num_controls;
57 struct op_msr *counters = msrs->counters; 80 struct op_msr *counters = msrs->counters;
58 struct op_msr *controls = msrs->controls; 81 struct op_msr *controls = msrs->controls;
59 unsigned int i; 82 unsigned int i;
60 83
61 for (i = 0; i < nr_ctrs; ++i) { 84 for (i = 0; i < model->num_counters; ++i) {
62 if (counters[i].addr) { 85 if (counters[i].addr)
63 rdmsr(counters[i].addr, 86 rdmsrl(counters[i].addr, counters[i].saved);
64 counters[i].saved.low, 87 }
65 counters[i].saved.high); 88
66 } 89 for (i = 0; i < model->num_controls; ++i) {
90 if (controls[i].addr)
91 rdmsrl(controls[i].addr, controls[i].saved);
92 }
93}
94
95static void nmi_cpu_start(void *dummy)
96{
97 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
98 model->start(msrs);
99}
100
101static int nmi_start(void)
102{
103 on_each_cpu(nmi_cpu_start, NULL, 1);
104 return 0;
105}
106
107static void nmi_cpu_stop(void *dummy)
108{
109 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
110 model->stop(msrs);
111}
112
113static void nmi_stop(void)
114{
115 on_each_cpu(nmi_cpu_stop, NULL, 1);
116}
117
118#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
119
120static DEFINE_PER_CPU(int, switch_index);
121
122static inline int has_mux(void)
123{
124 return !!model->switch_ctrl;
125}
126
127inline int op_x86_phys_to_virt(int phys)
128{
129 return __get_cpu_var(switch_index) + phys;
130}
131
132inline int op_x86_virt_to_phys(int virt)
133{
134 return virt % model->num_counters;
135}
136
137static void nmi_shutdown_mux(void)
138{
139 int i;
140
141 if (!has_mux())
142 return;
143
144 for_each_possible_cpu(i) {
145 kfree(per_cpu(cpu_msrs, i).multiplex);
146 per_cpu(cpu_msrs, i).multiplex = NULL;
147 per_cpu(switch_index, i) = 0;
67 } 148 }
149}
150
151static int nmi_setup_mux(void)
152{
153 size_t multiplex_size =
154 sizeof(struct op_msr) * model->num_virt_counters;
155 int i;
156
157 if (!has_mux())
158 return 1;
159
160 for_each_possible_cpu(i) {
161 per_cpu(cpu_msrs, i).multiplex =
162 kmalloc(multiplex_size, GFP_KERNEL);
163 if (!per_cpu(cpu_msrs, i).multiplex)
164 return 0;
165 }
166
167 return 1;
168}
169
170static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs)
171{
172 int i;
173 struct op_msr *multiplex = msrs->multiplex;
174
175 if (!has_mux())
176 return;
68 177
69 for (i = 0; i < nr_ctrls; ++i) { 178 for (i = 0; i < model->num_virt_counters; ++i) {
70 if (controls[i].addr) { 179 if (counter_config[i].enabled) {
71 rdmsr(controls[i].addr, 180 multiplex[i].saved = -(u64)counter_config[i].count;
72 controls[i].saved.low, 181 } else {
73 controls[i].saved.high); 182 multiplex[i].addr = 0;
183 multiplex[i].saved = 0;
74 } 184 }
75 } 185 }
186
187 per_cpu(switch_index, cpu) = 0;
188}
189
190static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs)
191{
192 struct op_msr *multiplex = msrs->multiplex;
193 int i;
194
195 for (i = 0; i < model->num_counters; ++i) {
196 int virt = op_x86_phys_to_virt(i);
197 if (multiplex[virt].addr)
198 rdmsrl(multiplex[virt].addr, multiplex[virt].saved);
199 }
200}
201
202static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs)
203{
204 struct op_msr *multiplex = msrs->multiplex;
205 int i;
206
207 for (i = 0; i < model->num_counters; ++i) {
208 int virt = op_x86_phys_to_virt(i);
209 if (multiplex[virt].addr)
210 wrmsrl(multiplex[virt].addr, multiplex[virt].saved);
211 }
76} 212}
77 213
78static void nmi_save_registers(void *dummy) 214static void nmi_cpu_switch(void *dummy)
79{ 215{
80 int cpu = smp_processor_id(); 216 int cpu = smp_processor_id();
217 int si = per_cpu(switch_index, cpu);
81 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 218 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
82 nmi_cpu_save_registers(msrs); 219
220 nmi_cpu_stop(NULL);
221 nmi_cpu_save_mpx_registers(msrs);
222
223 /* move to next set */
224 si += model->num_counters;
225 if ((si > model->num_virt_counters) || (counter_config[si].count == 0))
226 per_cpu(switch_index, cpu) = 0;
227 else
228 per_cpu(switch_index, cpu) = si;
229
230 model->switch_ctrl(model, msrs);
231 nmi_cpu_restore_mpx_registers(msrs);
232
233 nmi_cpu_start(NULL);
234}
235
236
237/*
238 * Quick check to see if multiplexing is necessary.
239 * The check should be sufficient since counters are used
240 * in ordre.
241 */
242static int nmi_multiplex_on(void)
243{
244 return counter_config[model->num_counters].count ? 0 : -EINVAL;
245}
246
247static int nmi_switch_event(void)
248{
249 if (!has_mux())
250 return -ENOSYS; /* not implemented */
251 if (nmi_multiplex_on() < 0)
252 return -EINVAL; /* not necessary */
253
254 on_each_cpu(nmi_cpu_switch, NULL, 1);
255
256 return 0;
257}
258
259static inline void mux_init(struct oprofile_operations *ops)
260{
261 if (has_mux())
262 ops->switch_events = nmi_switch_event;
263}
264
265static void mux_clone(int cpu)
266{
267 if (!has_mux())
268 return;
269
270 memcpy(per_cpu(cpu_msrs, cpu).multiplex,
271 per_cpu(cpu_msrs, 0).multiplex,
272 sizeof(struct op_msr) * model->num_virt_counters);
83} 273}
84 274
275#else
276
277inline int op_x86_phys_to_virt(int phys) { return phys; }
278inline int op_x86_virt_to_phys(int virt) { return virt; }
279static inline void nmi_shutdown_mux(void) { }
280static inline int nmi_setup_mux(void) { return 1; }
281static inline void
282nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) { }
283static inline void mux_init(struct oprofile_operations *ops) { }
284static void mux_clone(int cpu) { }
285
286#endif
287
85static void free_msrs(void) 288static void free_msrs(void)
86{ 289{
87 int i; 290 int i;
@@ -95,38 +298,32 @@ static void free_msrs(void)
95 298
96static int allocate_msrs(void) 299static int allocate_msrs(void)
97{ 300{
98 int success = 1;
99 size_t controls_size = sizeof(struct op_msr) * model->num_controls; 301 size_t controls_size = sizeof(struct op_msr) * model->num_controls;
100 size_t counters_size = sizeof(struct op_msr) * model->num_counters; 302 size_t counters_size = sizeof(struct op_msr) * model->num_counters;
101 303
102 int i; 304 int i;
103 for_each_possible_cpu(i) { 305 for_each_possible_cpu(i) {
104 per_cpu(cpu_msrs, i).counters = kmalloc(counters_size, 306 per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
105 GFP_KERNEL); 307 GFP_KERNEL);
106 if (!per_cpu(cpu_msrs, i).counters) { 308 if (!per_cpu(cpu_msrs, i).counters)
107 success = 0; 309 return 0;
108 break;
109 }
110 per_cpu(cpu_msrs, i).controls = kmalloc(controls_size, 310 per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
111 GFP_KERNEL); 311 GFP_KERNEL);
112 if (!per_cpu(cpu_msrs, i).controls) { 312 if (!per_cpu(cpu_msrs, i).controls)
113 success = 0; 313 return 0;
114 break;
115 }
116 } 314 }
117 315
118 if (!success) 316 return 1;
119 free_msrs();
120
121 return success;
122} 317}
123 318
124static void nmi_cpu_setup(void *dummy) 319static void nmi_cpu_setup(void *dummy)
125{ 320{
126 int cpu = smp_processor_id(); 321 int cpu = smp_processor_id();
127 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); 322 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
323 nmi_cpu_save_registers(msrs);
128 spin_lock(&oprofilefs_lock); 324 spin_lock(&oprofilefs_lock);
129 model->setup_ctrs(msrs); 325 model->setup_ctrs(model, msrs);
326 nmi_cpu_setup_mux(cpu, msrs);
130 spin_unlock(&oprofilefs_lock); 327 spin_unlock(&oprofilefs_lock);
131 per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); 328 per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC);
132 apic_write(APIC_LVTPC, APIC_DM_NMI); 329 apic_write(APIC_LVTPC, APIC_DM_NMI);
@@ -144,11 +341,15 @@ static int nmi_setup(void)
144 int cpu; 341 int cpu;
145 342
146 if (!allocate_msrs()) 343 if (!allocate_msrs())
147 return -ENOMEM; 344 err = -ENOMEM;
345 else if (!nmi_setup_mux())
346 err = -ENOMEM;
347 else
348 err = register_die_notifier(&profile_exceptions_nb);
148 349
149 err = register_die_notifier(&profile_exceptions_nb);
150 if (err) { 350 if (err) {
151 free_msrs(); 351 free_msrs();
352 nmi_shutdown_mux();
152 return err; 353 return err;
153 } 354 }
154 355
@@ -159,45 +360,38 @@ static int nmi_setup(void)
159 /* Assume saved/restored counters are the same on all CPUs */ 360 /* Assume saved/restored counters are the same on all CPUs */
160 model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); 361 model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
161 for_each_possible_cpu(cpu) { 362 for_each_possible_cpu(cpu) {
162 if (cpu != 0) { 363 if (!cpu)
163 memcpy(per_cpu(cpu_msrs, cpu).counters, 364 continue;
164 per_cpu(cpu_msrs, 0).counters, 365
165 sizeof(struct op_msr) * model->num_counters); 366 memcpy(per_cpu(cpu_msrs, cpu).counters,
166 367 per_cpu(cpu_msrs, 0).counters,
167 memcpy(per_cpu(cpu_msrs, cpu).controls, 368 sizeof(struct op_msr) * model->num_counters);
168 per_cpu(cpu_msrs, 0).controls, 369
169 sizeof(struct op_msr) * model->num_controls); 370 memcpy(per_cpu(cpu_msrs, cpu).controls,
170 } 371 per_cpu(cpu_msrs, 0).controls,
372 sizeof(struct op_msr) * model->num_controls);
171 373
374 mux_clone(cpu);
172 } 375 }
173 on_each_cpu(nmi_save_registers, NULL, 1);
174 on_each_cpu(nmi_cpu_setup, NULL, 1); 376 on_each_cpu(nmi_cpu_setup, NULL, 1);
175 nmi_enabled = 1; 377 nmi_enabled = 1;
176 return 0; 378 return 0;
177} 379}
178 380
179static void nmi_restore_registers(struct op_msrs *msrs) 381static void nmi_cpu_restore_registers(struct op_msrs *msrs)
180{ 382{
181 unsigned int const nr_ctrs = model->num_counters;
182 unsigned int const nr_ctrls = model->num_controls;
183 struct op_msr *counters = msrs->counters; 383 struct op_msr *counters = msrs->counters;
184 struct op_msr *controls = msrs->controls; 384 struct op_msr *controls = msrs->controls;
185 unsigned int i; 385 unsigned int i;
186 386
187 for (i = 0; i < nr_ctrls; ++i) { 387 for (i = 0; i < model->num_controls; ++i) {
188 if (controls[i].addr) { 388 if (controls[i].addr)
189 wrmsr(controls[i].addr, 389 wrmsrl(controls[i].addr, controls[i].saved);
190 controls[i].saved.low,
191 controls[i].saved.high);
192 }
193 } 390 }
194 391
195 for (i = 0; i < nr_ctrs; ++i) { 392 for (i = 0; i < model->num_counters; ++i) {
196 if (counters[i].addr) { 393 if (counters[i].addr)
197 wrmsr(counters[i].addr, 394 wrmsrl(counters[i].addr, counters[i].saved);
198 counters[i].saved.low,
199 counters[i].saved.high);
200 }
201 } 395 }
202} 396}
203 397
@@ -205,7 +399,7 @@ static void nmi_cpu_shutdown(void *dummy)
205{ 399{
206 unsigned int v; 400 unsigned int v;
207 int cpu = smp_processor_id(); 401 int cpu = smp_processor_id();
208 struct op_msrs *msrs = &__get_cpu_var(cpu_msrs); 402 struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu);
209 403
210 /* restoring APIC_LVTPC can trigger an apic error because the delivery 404 /* restoring APIC_LVTPC can trigger an apic error because the delivery
211 * mode and vector nr combination can be illegal. That's by design: on 405 * mode and vector nr combination can be illegal. That's by design: on
@@ -216,7 +410,7 @@ static void nmi_cpu_shutdown(void *dummy)
216 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); 410 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
217 apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); 411 apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
218 apic_write(APIC_LVTERR, v); 412 apic_write(APIC_LVTERR, v);
219 nmi_restore_registers(msrs); 413 nmi_cpu_restore_registers(msrs);
220} 414}
221 415
222static void nmi_shutdown(void) 416static void nmi_shutdown(void)
@@ -226,42 +420,18 @@ static void nmi_shutdown(void)
226 nmi_enabled = 0; 420 nmi_enabled = 0;
227 on_each_cpu(nmi_cpu_shutdown, NULL, 1); 421 on_each_cpu(nmi_cpu_shutdown, NULL, 1);
228 unregister_die_notifier(&profile_exceptions_nb); 422 unregister_die_notifier(&profile_exceptions_nb);
423 nmi_shutdown_mux();
229 msrs = &get_cpu_var(cpu_msrs); 424 msrs = &get_cpu_var(cpu_msrs);
230 model->shutdown(msrs); 425 model->shutdown(msrs);
231 free_msrs(); 426 free_msrs();
232 put_cpu_var(cpu_msrs); 427 put_cpu_var(cpu_msrs);
233} 428}
234 429
235static void nmi_cpu_start(void *dummy)
236{
237 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
238 model->start(msrs);
239}
240
241static int nmi_start(void)
242{
243 on_each_cpu(nmi_cpu_start, NULL, 1);
244 return 0;
245}
246
247static void nmi_cpu_stop(void *dummy)
248{
249 struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
250 model->stop(msrs);
251}
252
253static void nmi_stop(void)
254{
255 on_each_cpu(nmi_cpu_stop, NULL, 1);
256}
257
258struct op_counter_config counter_config[OP_MAX_COUNTER];
259
260static int nmi_create_files(struct super_block *sb, struct dentry *root) 430static int nmi_create_files(struct super_block *sb, struct dentry *root)
261{ 431{
262 unsigned int i; 432 unsigned int i;
263 433
264 for (i = 0; i < model->num_counters; ++i) { 434 for (i = 0; i < model->num_virt_counters; ++i) {
265 struct dentry *dir; 435 struct dentry *dir;
266 char buf[4]; 436 char buf[4];
267 437
@@ -270,7 +440,7 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root)
270 * NOTE: assumes 1:1 mapping here (that counters are organized 440 * NOTE: assumes 1:1 mapping here (that counters are organized
271 * sequentially in their struct assignment). 441 * sequentially in their struct assignment).
272 */ 442 */
273 if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i))) 443 if (!avail_to_resrv_perfctr_nmi_bit(op_x86_virt_to_phys(i)))
274 continue; 444 continue;
275 445
276 snprintf(buf, sizeof(buf), "%d", i); 446 snprintf(buf, sizeof(buf), "%d", i);
@@ -402,6 +572,7 @@ module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0);
402static int __init ppro_init(char **cpu_type) 572static int __init ppro_init(char **cpu_type)
403{ 573{
404 __u8 cpu_model = boot_cpu_data.x86_model; 574 __u8 cpu_model = boot_cpu_data.x86_model;
575 struct op_x86_model_spec *spec = &op_ppro_spec; /* default */
405 576
406 if (force_arch_perfmon && cpu_has_arch_perfmon) 577 if (force_arch_perfmon && cpu_has_arch_perfmon)
407 return 0; 578 return 0;
@@ -428,7 +599,7 @@ static int __init ppro_init(char **cpu_type)
428 *cpu_type = "i386/core_2"; 599 *cpu_type = "i386/core_2";
429 break; 600 break;
430 case 26: 601 case 26:
431 arch_perfmon_setup_counters(); 602 spec = &op_arch_perfmon_spec;
432 *cpu_type = "i386/core_i7"; 603 *cpu_type = "i386/core_i7";
433 break; 604 break;
434 case 28: 605 case 28:
@@ -439,17 +610,7 @@ static int __init ppro_init(char **cpu_type)
439 return 0; 610 return 0;
440 } 611 }
441 612
442 model = &op_ppro_spec; 613 model = spec;
443 return 1;
444}
445
446static int __init arch_perfmon_init(char **cpu_type)
447{
448 if (!cpu_has_arch_perfmon)
449 return 0;
450 *cpu_type = "i386/arch_perfmon";
451 model = &op_arch_perfmon_spec;
452 arch_perfmon_setup_counters();
453 return 1; 614 return 1;
454} 615}
455 616
@@ -471,27 +632,26 @@ int __init op_nmi_init(struct oprofile_operations *ops)
471 /* Needs to be at least an Athlon (or hammer in 32bit mode) */ 632 /* Needs to be at least an Athlon (or hammer in 32bit mode) */
472 633
473 switch (family) { 634 switch (family) {
474 default:
475 return -ENODEV;
476 case 6: 635 case 6:
477 model = &op_amd_spec;
478 cpu_type = "i386/athlon"; 636 cpu_type = "i386/athlon";
479 break; 637 break;
480 case 0xf: 638 case 0xf:
481 model = &op_amd_spec; 639 /*
482 /* Actually it could be i386/hammer too, but give 640 * Actually it could be i386/hammer too, but
483 user space an consistent name. */ 641 * give user space an consistent name.
642 */
484 cpu_type = "x86-64/hammer"; 643 cpu_type = "x86-64/hammer";
485 break; 644 break;
486 case 0x10: 645 case 0x10:
487 model = &op_amd_spec;
488 cpu_type = "x86-64/family10"; 646 cpu_type = "x86-64/family10";
489 break; 647 break;
490 case 0x11: 648 case 0x11:
491 model = &op_amd_spec;
492 cpu_type = "x86-64/family11h"; 649 cpu_type = "x86-64/family11h";
493 break; 650 break;
651 default:
652 return -ENODEV;
494 } 653 }
654 model = &op_amd_spec;
495 break; 655 break;
496 656
497 case X86_VENDOR_INTEL: 657 case X86_VENDOR_INTEL:
@@ -510,8 +670,15 @@ int __init op_nmi_init(struct oprofile_operations *ops)
510 break; 670 break;
511 } 671 }
512 672
513 if (!cpu_type && !arch_perfmon_init(&cpu_type)) 673 if (cpu_type)
674 break;
675
676 if (!cpu_has_arch_perfmon)
514 return -ENODEV; 677 return -ENODEV;
678
679 /* use arch perfmon as fallback */
680 cpu_type = "i386/arch_perfmon";
681 model = &op_arch_perfmon_spec;
515 break; 682 break;
516 683
517 default: 684 default:
@@ -522,18 +689,23 @@ int __init op_nmi_init(struct oprofile_operations *ops)
522 register_cpu_notifier(&oprofile_cpu_nb); 689 register_cpu_notifier(&oprofile_cpu_nb);
523#endif 690#endif
524 /* default values, can be overwritten by model */ 691 /* default values, can be overwritten by model */
525 ops->create_files = nmi_create_files; 692 ops->create_files = nmi_create_files;
526 ops->setup = nmi_setup; 693 ops->setup = nmi_setup;
527 ops->shutdown = nmi_shutdown; 694 ops->shutdown = nmi_shutdown;
528 ops->start = nmi_start; 695 ops->start = nmi_start;
529 ops->stop = nmi_stop; 696 ops->stop = nmi_stop;
530 ops->cpu_type = cpu_type; 697 ops->cpu_type = cpu_type;
531 698
532 if (model->init) 699 if (model->init)
533 ret = model->init(ops); 700 ret = model->init(ops);
534 if (ret) 701 if (ret)
535 return ret; 702 return ret;
536 703
704 if (!model->num_virt_counters)
705 model->num_virt_counters = model->num_counters;
706
707 mux_init(ops);
708
537 init_sysfs(); 709 init_sysfs();
538 using_nmi = 1; 710 using_nmi = 1;
539 printk(KERN_INFO "oprofile: using NMI interrupt.\n"); 711 printk(KERN_INFO "oprofile: using NMI interrupt.\n");
diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h
index 91b6a116165e..e28398df0df2 100644
--- a/arch/x86/oprofile/op_counter.h
+++ b/arch/x86/oprofile/op_counter.h
@@ -10,7 +10,7 @@
10#ifndef OP_COUNTER_H 10#ifndef OP_COUNTER_H
11#define OP_COUNTER_H 11#define OP_COUNTER_H
12 12
13#define OP_MAX_COUNTER 8 13#define OP_MAX_COUNTER 32
14 14
15/* Per-perfctr configuration as set via 15/* Per-perfctr configuration as set via
16 * oprofilefs. 16 * oprofilefs.
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 8fdf06e4edf9..39686c29f03a 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -9,12 +9,15 @@
9 * @author Philippe Elie 9 * @author Philippe Elie
10 * @author Graydon Hoare 10 * @author Graydon Hoare
11 * @author Robert Richter <robert.richter@amd.com> 11 * @author Robert Richter <robert.richter@amd.com>
12 * @author Barry Kasindorf 12 * @author Barry Kasindorf <barry.kasindorf@amd.com>
13 * @author Jason Yeh <jason.yeh@amd.com>
14 * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
13 */ 15 */
14 16
15#include <linux/oprofile.h> 17#include <linux/oprofile.h>
16#include <linux/device.h> 18#include <linux/device.h>
17#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/percpu.h>
18 21
19#include <asm/ptrace.h> 22#include <asm/ptrace.h>
20#include <asm/msr.h> 23#include <asm/msr.h>
@@ -25,43 +28,36 @@
25 28
26#define NUM_COUNTERS 4 29#define NUM_COUNTERS 4
27#define NUM_CONTROLS 4 30#define NUM_CONTROLS 4
31#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
32#define NUM_VIRT_COUNTERS 32
33#define NUM_VIRT_CONTROLS 32
34#else
35#define NUM_VIRT_COUNTERS NUM_COUNTERS
36#define NUM_VIRT_CONTROLS NUM_CONTROLS
37#endif
38
39#define OP_EVENT_MASK 0x0FFF
40#define OP_CTR_OVERFLOW (1ULL<<31)
28 41
29#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) 42#define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21))
30#define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0) 43
31#define CTR_WRITE(l, msrs, c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1); } while (0) 44static unsigned long reset_value[NUM_VIRT_COUNTERS];
32#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
33
34#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
35#define CTRL_READ(l, h, msrs, c) do {rdmsr(msrs->controls[(c)].addr, (l), (h)); } while (0)
36#define CTRL_WRITE(l, h, msrs, c) do {wrmsr(msrs->controls[(c)].addr, (l), (h)); } while (0)
37#define CTRL_SET_ACTIVE(n) (n |= (1<<22))
38#define CTRL_SET_INACTIVE(n) (n &= ~(1<<22))
39#define CTRL_CLEAR_LO(x) (x &= (1<<21))
40#define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0)
41#define CTRL_SET_ENABLE(val) (val |= 1<<20)
42#define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16))
43#define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17))
44#define CTRL_SET_UM(val, m) (val |= (m << 8))
45#define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff))
46#define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf))
47#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9))
48#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8))
49
50static unsigned long reset_value[NUM_COUNTERS];
51 45
52#ifdef CONFIG_OPROFILE_IBS 46#ifdef CONFIG_OPROFILE_IBS
53 47
54/* IbsFetchCtl bits/masks */ 48/* IbsFetchCtl bits/masks */
55#define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */ 49#define IBS_FETCH_RAND_EN (1ULL<<57)
56#define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */ 50#define IBS_FETCH_VAL (1ULL<<49)
57#define IBS_FETCH_LOW_MAX_CNT_MASK 0x0000FFFFUL /* MaxCnt mask */ 51#define IBS_FETCH_ENABLE (1ULL<<48)
52#define IBS_FETCH_CNT_MASK 0xFFFF0000ULL
58 53
59/*IbsOpCtl bits */ 54/*IbsOpCtl bits */
60#define IBS_OP_LOW_VALID_BIT (1ULL<<18) /* bit 18 */ 55#define IBS_OP_CNT_CTL (1ULL<<19)
61#define IBS_OP_LOW_ENABLE (1ULL<<17) /* bit 17 */ 56#define IBS_OP_VAL (1ULL<<18)
57#define IBS_OP_ENABLE (1ULL<<17)
62 58
63#define IBS_FETCH_SIZE 6 59#define IBS_FETCH_SIZE 6
64#define IBS_OP_SIZE 12 60#define IBS_OP_SIZE 12
65 61
66static int has_ibs; /* AMD Family10h and later */ 62static int has_ibs; /* AMD Family10h and later */
67 63
@@ -78,6 +74,45 @@ static struct op_ibs_config ibs_config;
78 74
79#endif 75#endif
80 76
77#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
78
79static void op_mux_fill_in_addresses(struct op_msrs * const msrs)
80{
81 int i;
82
83 for (i = 0; i < NUM_VIRT_COUNTERS; i++) {
84 int hw_counter = op_x86_virt_to_phys(i);
85 if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
86 msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter;
87 else
88 msrs->multiplex[i].addr = 0;
89 }
90}
91
92static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
93 struct op_msrs const * const msrs)
94{
95 u64 val;
96 int i;
97
98 /* enable active counters */
99 for (i = 0; i < NUM_COUNTERS; ++i) {
100 int virt = op_x86_phys_to_virt(i);
101 if (!counter_config[virt].enabled)
102 continue;
103 rdmsrl(msrs->controls[i].addr, val);
104 val &= model->reserved;
105 val |= op_x86_get_ctrl(model, &counter_config[virt]);
106 wrmsrl(msrs->controls[i].addr, val);
107 }
108}
109
110#else
111
112static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { }
113
114#endif
115
81/* functions for op_amd_spec */ 116/* functions for op_amd_spec */
82 117
83static void op_amd_fill_in_addresses(struct op_msrs * const msrs) 118static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
@@ -97,150 +132,174 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
97 else 132 else
98 msrs->controls[i].addr = 0; 133 msrs->controls[i].addr = 0;
99 } 134 }
100}
101 135
136 op_mux_fill_in_addresses(msrs);
137}
102 138
103static void op_amd_setup_ctrs(struct op_msrs const * const msrs) 139static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
140 struct op_msrs const * const msrs)
104{ 141{
105 unsigned int low, high; 142 u64 val;
106 int i; 143 int i;
107 144
145 /* setup reset_value */
146 for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
147 if (counter_config[i].enabled)
148 reset_value[i] = counter_config[i].count;
149 else
150 reset_value[i] = 0;
151 }
152
108 /* clear all counters */ 153 /* clear all counters */
109 for (i = 0 ; i < NUM_CONTROLS; ++i) { 154 for (i = 0; i < NUM_CONTROLS; ++i) {
110 if (unlikely(!CTRL_IS_RESERVED(msrs, i))) 155 if (unlikely(!msrs->controls[i].addr))
111 continue; 156 continue;
112 CTRL_READ(low, high, msrs, i); 157 rdmsrl(msrs->controls[i].addr, val);
113 CTRL_CLEAR_LO(low); 158 val &= model->reserved;
114 CTRL_CLEAR_HI(high); 159 wrmsrl(msrs->controls[i].addr, val);
115 CTRL_WRITE(low, high, msrs, i);
116 } 160 }
117 161
118 /* avoid a false detection of ctr overflows in NMI handler */ 162 /* avoid a false detection of ctr overflows in NMI handler */
119 for (i = 0; i < NUM_COUNTERS; ++i) { 163 for (i = 0; i < NUM_COUNTERS; ++i) {
120 if (unlikely(!CTR_IS_RESERVED(msrs, i))) 164 if (unlikely(!msrs->counters[i].addr))
121 continue; 165 continue;
122 CTR_WRITE(1, msrs, i); 166 wrmsrl(msrs->counters[i].addr, -1LL);
123 } 167 }
124 168
125 /* enable active counters */ 169 /* enable active counters */
126 for (i = 0; i < NUM_COUNTERS; ++i) { 170 for (i = 0; i < NUM_COUNTERS; ++i) {
127 if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { 171 int virt = op_x86_phys_to_virt(i);
128 reset_value[i] = counter_config[i].count; 172 if (!counter_config[virt].enabled)
173 continue;
174 if (!msrs->counters[i].addr)
175 continue;
129 176
130 CTR_WRITE(counter_config[i].count, msrs, i); 177 /* setup counter registers */
131 178 wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]);
132 CTRL_READ(low, high, msrs, i); 179
133 CTRL_CLEAR_LO(low); 180 /* setup control registers */
134 CTRL_CLEAR_HI(high); 181 rdmsrl(msrs->controls[i].addr, val);
135 CTRL_SET_ENABLE(low); 182 val &= model->reserved;
136 CTRL_SET_USR(low, counter_config[i].user); 183 val |= op_x86_get_ctrl(model, &counter_config[virt]);
137 CTRL_SET_KERN(low, counter_config[i].kernel); 184 wrmsrl(msrs->controls[i].addr, val);
138 CTRL_SET_UM(low, counter_config[i].unit_mask);
139 CTRL_SET_EVENT_LOW(low, counter_config[i].event);
140 CTRL_SET_EVENT_HIGH(high, counter_config[i].event);
141 CTRL_SET_HOST_ONLY(high, 0);
142 CTRL_SET_GUEST_ONLY(high, 0);
143
144 CTRL_WRITE(low, high, msrs, i);
145 } else {
146 reset_value[i] = 0;
147 }
148 } 185 }
149} 186}
150 187
151#ifdef CONFIG_OPROFILE_IBS 188#ifdef CONFIG_OPROFILE_IBS
152 189
153static inline int 190static inline void
154op_amd_handle_ibs(struct pt_regs * const regs, 191op_amd_handle_ibs(struct pt_regs * const regs,
155 struct op_msrs const * const msrs) 192 struct op_msrs const * const msrs)
156{ 193{
157 u32 low, high; 194 u64 val, ctl;
158 u64 msr;
159 struct op_entry entry; 195 struct op_entry entry;
160 196
161 if (!has_ibs) 197 if (!has_ibs)
162 return 1; 198 return;
163 199
164 if (ibs_config.fetch_enabled) { 200 if (ibs_config.fetch_enabled) {
165 rdmsr(MSR_AMD64_IBSFETCHCTL, low, high); 201 rdmsrl(MSR_AMD64_IBSFETCHCTL, ctl);
166 if (high & IBS_FETCH_HIGH_VALID_BIT) { 202 if (ctl & IBS_FETCH_VAL) {
167 rdmsrl(MSR_AMD64_IBSFETCHLINAD, msr); 203 rdmsrl(MSR_AMD64_IBSFETCHLINAD, val);
168 oprofile_write_reserve(&entry, regs, msr, 204 oprofile_write_reserve(&entry, regs, val,
169 IBS_FETCH_CODE, IBS_FETCH_SIZE); 205 IBS_FETCH_CODE, IBS_FETCH_SIZE);
170 oprofile_add_data(&entry, (u32)msr); 206 oprofile_add_data64(&entry, val);
171 oprofile_add_data(&entry, (u32)(msr >> 32)); 207 oprofile_add_data64(&entry, ctl);
172 oprofile_add_data(&entry, low); 208 rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, val);
173 oprofile_add_data(&entry, high); 209 oprofile_add_data64(&entry, val);
174 rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, msr);
175 oprofile_add_data(&entry, (u32)msr);
176 oprofile_add_data(&entry, (u32)(msr >> 32));
177 oprofile_write_commit(&entry); 210 oprofile_write_commit(&entry);
178 211
179 /* reenable the IRQ */ 212 /* reenable the IRQ */
180 high &= ~IBS_FETCH_HIGH_VALID_BIT; 213 ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT_MASK);
181 high |= IBS_FETCH_HIGH_ENABLE; 214 ctl |= IBS_FETCH_ENABLE;
182 low &= IBS_FETCH_LOW_MAX_CNT_MASK; 215 wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl);
183 wrmsr(MSR_AMD64_IBSFETCHCTL, low, high);
184 } 216 }
185 } 217 }
186 218
187 if (ibs_config.op_enabled) { 219 if (ibs_config.op_enabled) {
188 rdmsr(MSR_AMD64_IBSOPCTL, low, high); 220 rdmsrl(MSR_AMD64_IBSOPCTL, ctl);
189 if (low & IBS_OP_LOW_VALID_BIT) { 221 if (ctl & IBS_OP_VAL) {
190 rdmsrl(MSR_AMD64_IBSOPRIP, msr); 222 rdmsrl(MSR_AMD64_IBSOPRIP, val);
191 oprofile_write_reserve(&entry, regs, msr, 223 oprofile_write_reserve(&entry, regs, val,
192 IBS_OP_CODE, IBS_OP_SIZE); 224 IBS_OP_CODE, IBS_OP_SIZE);
193 oprofile_add_data(&entry, (u32)msr); 225 oprofile_add_data64(&entry, val);
194 oprofile_add_data(&entry, (u32)(msr >> 32)); 226 rdmsrl(MSR_AMD64_IBSOPDATA, val);
195 rdmsrl(MSR_AMD64_IBSOPDATA, msr); 227 oprofile_add_data64(&entry, val);
196 oprofile_add_data(&entry, (u32)msr); 228 rdmsrl(MSR_AMD64_IBSOPDATA2, val);
197 oprofile_add_data(&entry, (u32)(msr >> 32)); 229 oprofile_add_data64(&entry, val);
198 rdmsrl(MSR_AMD64_IBSOPDATA2, msr); 230 rdmsrl(MSR_AMD64_IBSOPDATA3, val);
199 oprofile_add_data(&entry, (u32)msr); 231 oprofile_add_data64(&entry, val);
200 oprofile_add_data(&entry, (u32)(msr >> 32)); 232 rdmsrl(MSR_AMD64_IBSDCLINAD, val);
201 rdmsrl(MSR_AMD64_IBSOPDATA3, msr); 233 oprofile_add_data64(&entry, val);
202 oprofile_add_data(&entry, (u32)msr); 234 rdmsrl(MSR_AMD64_IBSDCPHYSAD, val);
203 oprofile_add_data(&entry, (u32)(msr >> 32)); 235 oprofile_add_data64(&entry, val);
204 rdmsrl(MSR_AMD64_IBSDCLINAD, msr);
205 oprofile_add_data(&entry, (u32)msr);
206 oprofile_add_data(&entry, (u32)(msr >> 32));
207 rdmsrl(MSR_AMD64_IBSDCPHYSAD, msr);
208 oprofile_add_data(&entry, (u32)msr);
209 oprofile_add_data(&entry, (u32)(msr >> 32));
210 oprofile_write_commit(&entry); 236 oprofile_write_commit(&entry);
211 237
212 /* reenable the IRQ */ 238 /* reenable the IRQ */
213 high = 0; 239 ctl &= ~IBS_OP_VAL & 0xFFFFFFFF;
214 low &= ~IBS_OP_LOW_VALID_BIT; 240 ctl |= IBS_OP_ENABLE;
215 low |= IBS_OP_LOW_ENABLE; 241 wrmsrl(MSR_AMD64_IBSOPCTL, ctl);
216 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
217 } 242 }
218 } 243 }
244}
219 245
220 return 1; 246static inline void op_amd_start_ibs(void)
247{
248 u64 val;
249 if (has_ibs && ibs_config.fetch_enabled) {
250 val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
251 val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0;
252 val |= IBS_FETCH_ENABLE;
253 wrmsrl(MSR_AMD64_IBSFETCHCTL, val);
254 }
255
256 if (has_ibs && ibs_config.op_enabled) {
257 val = (ibs_config.max_cnt_op >> 4) & 0xFFFF;
258 val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0;
259 val |= IBS_OP_ENABLE;
260 wrmsrl(MSR_AMD64_IBSOPCTL, val);
261 }
262}
263
264static void op_amd_stop_ibs(void)
265{
266 if (has_ibs && ibs_config.fetch_enabled)
267 /* clear max count and enable */
268 wrmsrl(MSR_AMD64_IBSFETCHCTL, 0);
269
270 if (has_ibs && ibs_config.op_enabled)
271 /* clear max count and enable */
272 wrmsrl(MSR_AMD64_IBSOPCTL, 0);
221} 273}
222 274
275#else
276
277static inline void op_amd_handle_ibs(struct pt_regs * const regs,
278 struct op_msrs const * const msrs) { }
279static inline void op_amd_start_ibs(void) { }
280static inline void op_amd_stop_ibs(void) { }
281
223#endif 282#endif
224 283
225static int op_amd_check_ctrs(struct pt_regs * const regs, 284static int op_amd_check_ctrs(struct pt_regs * const regs,
226 struct op_msrs const * const msrs) 285 struct op_msrs const * const msrs)
227{ 286{
228 unsigned int low, high; 287 u64 val;
229 int i; 288 int i;
230 289
231 for (i = 0 ; i < NUM_COUNTERS; ++i) { 290 for (i = 0; i < NUM_COUNTERS; ++i) {
232 if (!reset_value[i]) 291 int virt = op_x86_phys_to_virt(i);
292 if (!reset_value[virt])
233 continue; 293 continue;
234 CTR_READ(low, high, msrs, i); 294 rdmsrl(msrs->counters[i].addr, val);
235 if (CTR_OVERFLOWED(low)) { 295 /* bit is clear if overflowed: */
236 oprofile_add_sample(regs, i); 296 if (val & OP_CTR_OVERFLOW)
237 CTR_WRITE(reset_value[i], msrs, i); 297 continue;
238 } 298 oprofile_add_sample(regs, virt);
299 wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]);
239 } 300 }
240 301
241#ifdef CONFIG_OPROFILE_IBS
242 op_amd_handle_ibs(regs, msrs); 302 op_amd_handle_ibs(regs, msrs);
243#endif
244 303
245 /* See op_model_ppro.c */ 304 /* See op_model_ppro.c */
246 return 1; 305 return 1;
@@ -248,79 +307,50 @@ static int op_amd_check_ctrs(struct pt_regs * const regs,
248 307
249static void op_amd_start(struct op_msrs const * const msrs) 308static void op_amd_start(struct op_msrs const * const msrs)
250{ 309{
251 unsigned int low, high; 310 u64 val;
252 int i; 311 int i;
253 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
254 if (reset_value[i]) {
255 CTRL_READ(low, high, msrs, i);
256 CTRL_SET_ACTIVE(low);
257 CTRL_WRITE(low, high, msrs, i);
258 }
259 }
260 312
261#ifdef CONFIG_OPROFILE_IBS 313 for (i = 0; i < NUM_COUNTERS; ++i) {
262 if (has_ibs && ibs_config.fetch_enabled) { 314 if (!reset_value[op_x86_phys_to_virt(i)])
263 low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; 315 continue;
264 high = ((ibs_config.rand_en & 0x1) << 25) /* bit 57 */ 316 rdmsrl(msrs->controls[i].addr, val);
265 + IBS_FETCH_HIGH_ENABLE; 317 val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
266 wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); 318 wrmsrl(msrs->controls[i].addr, val);
267 } 319 }
268 320
269 if (has_ibs && ibs_config.op_enabled) { 321 op_amd_start_ibs();
270 low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF)
271 + ((ibs_config.dispatched_ops & 0x1) << 19) /* bit 19 */
272 + IBS_OP_LOW_ENABLE;
273 high = 0;
274 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
275 }
276#endif
277} 322}
278 323
279
280static void op_amd_stop(struct op_msrs const * const msrs) 324static void op_amd_stop(struct op_msrs const * const msrs)
281{ 325{
282 unsigned int low, high; 326 u64 val;
283 int i; 327 int i;
284 328
285 /* 329 /*
286 * Subtle: stop on all counters to avoid race with setting our 330 * Subtle: stop on all counters to avoid race with setting our
287 * pm callback 331 * pm callback
288 */ 332 */
289 for (i = 0 ; i < NUM_COUNTERS ; ++i) { 333 for (i = 0; i < NUM_COUNTERS; ++i) {
290 if (!reset_value[i]) 334 if (!reset_value[op_x86_phys_to_virt(i)])
291 continue; 335 continue;
292 CTRL_READ(low, high, msrs, i); 336 rdmsrl(msrs->controls[i].addr, val);
293 CTRL_SET_INACTIVE(low); 337 val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
294 CTRL_WRITE(low, high, msrs, i); 338 wrmsrl(msrs->controls[i].addr, val);
295 }
296
297#ifdef CONFIG_OPROFILE_IBS
298 if (has_ibs && ibs_config.fetch_enabled) {
299 /* clear max count and enable */
300 low = 0;
301 high = 0;
302 wrmsr(MSR_AMD64_IBSFETCHCTL, low, high);
303 } 339 }
304 340
305 if (has_ibs && ibs_config.op_enabled) { 341 op_amd_stop_ibs();
306 /* clear max count and enable */
307 low = 0;
308 high = 0;
309 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
310 }
311#endif
312} 342}
313 343
314static void op_amd_shutdown(struct op_msrs const * const msrs) 344static void op_amd_shutdown(struct op_msrs const * const msrs)
315{ 345{
316 int i; 346 int i;
317 347
318 for (i = 0 ; i < NUM_COUNTERS ; ++i) { 348 for (i = 0; i < NUM_COUNTERS; ++i) {
319 if (CTR_IS_RESERVED(msrs, i)) 349 if (msrs->counters[i].addr)
320 release_perfctr_nmi(MSR_K7_PERFCTR0 + i); 350 release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
321 } 351 }
322 for (i = 0 ; i < NUM_CONTROLS ; ++i) { 352 for (i = 0; i < NUM_CONTROLS; ++i) {
323 if (CTRL_IS_RESERVED(msrs, i)) 353 if (msrs->controls[i].addr)
324 release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); 354 release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
325 } 355 }
326} 356}
@@ -490,15 +520,21 @@ static void op_amd_exit(void) {}
490 520
491#endif /* CONFIG_OPROFILE_IBS */ 521#endif /* CONFIG_OPROFILE_IBS */
492 522
493struct op_x86_model_spec const op_amd_spec = { 523struct op_x86_model_spec op_amd_spec = {
494 .init = op_amd_init,
495 .exit = op_amd_exit,
496 .num_counters = NUM_COUNTERS, 524 .num_counters = NUM_COUNTERS,
497 .num_controls = NUM_CONTROLS, 525 .num_controls = NUM_CONTROLS,
526 .num_virt_counters = NUM_VIRT_COUNTERS,
527 .reserved = MSR_AMD_EVENTSEL_RESERVED,
528 .event_mask = OP_EVENT_MASK,
529 .init = op_amd_init,
530 .exit = op_amd_exit,
498 .fill_in_addresses = &op_amd_fill_in_addresses, 531 .fill_in_addresses = &op_amd_fill_in_addresses,
499 .setup_ctrs = &op_amd_setup_ctrs, 532 .setup_ctrs = &op_amd_setup_ctrs,
500 .check_ctrs = &op_amd_check_ctrs, 533 .check_ctrs = &op_amd_check_ctrs,
501 .start = &op_amd_start, 534 .start = &op_amd_start,
502 .stop = &op_amd_stop, 535 .stop = &op_amd_stop,
503 .shutdown = &op_amd_shutdown 536 .shutdown = &op_amd_shutdown,
537#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
538 .switch_ctrl = &op_mux_switch_ctrl,
539#endif
504}; 540};
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 819b131fd752..ac6b354becdf 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -32,6 +32,8 @@
32#define NUM_CCCRS_HT2 9 32#define NUM_CCCRS_HT2 9
33#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) 33#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2)
34 34
35#define OP_CTR_OVERFLOW (1ULL<<31)
36
35static unsigned int num_counters = NUM_COUNTERS_NON_HT; 37static unsigned int num_counters = NUM_COUNTERS_NON_HT;
36static unsigned int num_controls = NUM_CONTROLS_NON_HT; 38static unsigned int num_controls = NUM_CONTROLS_NON_HT;
37 39
@@ -350,8 +352,6 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
350#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1)) 352#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
351#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25)) 353#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25))
352#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9)) 354#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
353#define ESCR_READ(escr, high, ev, i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0)
354#define ESCR_WRITE(escr, high, ev, i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0)
355 355
356#define CCCR_RESERVED_BITS 0x38030FFF 356#define CCCR_RESERVED_BITS 0x38030FFF
357#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) 357#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
@@ -361,17 +361,9 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
361#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) 361#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
362#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) 362#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
363#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) 363#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
364#define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0)
365#define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0)
366#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) 364#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
367#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) 365#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
368 366
369#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
370#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
371#define CTR_READ(l, h, i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h)); } while (0)
372#define CTR_WRITE(l, i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1); } while (0)
373#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
374
375 367
376/* this assigns a "stagger" to the current CPU, which is used throughout 368/* this assigns a "stagger" to the current CPU, which is used throughout
377 the code in this module as an extra array offset, to select the "even" 369 the code in this module as an extra array offset, to select the "even"
@@ -515,7 +507,7 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
515 if (ev->bindings[i].virt_counter & counter_bit) { 507 if (ev->bindings[i].virt_counter & counter_bit) {
516 508
517 /* modify ESCR */ 509 /* modify ESCR */
518 ESCR_READ(escr, high, ev, i); 510 rdmsr(ev->bindings[i].escr_address, escr, high);
519 ESCR_CLEAR(escr); 511 ESCR_CLEAR(escr);
520 if (stag == 0) { 512 if (stag == 0) {
521 ESCR_SET_USR_0(escr, counter_config[ctr].user); 513 ESCR_SET_USR_0(escr, counter_config[ctr].user);
@@ -526,10 +518,11 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
526 } 518 }
527 ESCR_SET_EVENT_SELECT(escr, ev->event_select); 519 ESCR_SET_EVENT_SELECT(escr, ev->event_select);
528 ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); 520 ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);
529 ESCR_WRITE(escr, high, ev, i); 521 wrmsr(ev->bindings[i].escr_address, escr, high);
530 522
531 /* modify CCCR */ 523 /* modify CCCR */
532 CCCR_READ(cccr, high, VIRT_CTR(stag, ctr)); 524 rdmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address,
525 cccr, high);
533 CCCR_CLEAR(cccr); 526 CCCR_CLEAR(cccr);
534 CCCR_SET_REQUIRED_BITS(cccr); 527 CCCR_SET_REQUIRED_BITS(cccr);
535 CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); 528 CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
@@ -537,7 +530,8 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
537 CCCR_SET_PMI_OVF_0(cccr); 530 CCCR_SET_PMI_OVF_0(cccr);
538 else 531 else
539 CCCR_SET_PMI_OVF_1(cccr); 532 CCCR_SET_PMI_OVF_1(cccr);
540 CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr)); 533 wrmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address,
534 cccr, high);
541 return; 535 return;
542 } 536 }
543 } 537 }
@@ -548,7 +542,8 @@ static void pmc_setup_one_p4_counter(unsigned int ctr)
548} 542}
549 543
550 544
551static void p4_setup_ctrs(struct op_msrs const * const msrs) 545static void p4_setup_ctrs(struct op_x86_model_spec const *model,
546 struct op_msrs const * const msrs)
552{ 547{
553 unsigned int i; 548 unsigned int i;
554 unsigned int low, high; 549 unsigned int low, high;
@@ -563,8 +558,8 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
563 } 558 }
564 559
565 /* clear the cccrs we will use */ 560 /* clear the cccrs we will use */
566 for (i = 0 ; i < num_counters ; i++) { 561 for (i = 0; i < num_counters; i++) {
567 if (unlikely(!CTRL_IS_RESERVED(msrs, i))) 562 if (unlikely(!msrs->controls[i].addr))
568 continue; 563 continue;
569 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 564 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
570 CCCR_CLEAR(low); 565 CCCR_CLEAR(low);
@@ -574,17 +569,18 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
574 569
575 /* clear all escrs (including those outside our concern) */ 570 /* clear all escrs (including those outside our concern) */
576 for (i = num_counters; i < num_controls; i++) { 571 for (i = num_counters; i < num_controls; i++) {
577 if (unlikely(!CTRL_IS_RESERVED(msrs, i))) 572 if (unlikely(!msrs->controls[i].addr))
578 continue; 573 continue;
579 wrmsr(msrs->controls[i].addr, 0, 0); 574 wrmsr(msrs->controls[i].addr, 0, 0);
580 } 575 }
581 576
582 /* setup all counters */ 577 /* setup all counters */
583 for (i = 0 ; i < num_counters ; ++i) { 578 for (i = 0; i < num_counters; ++i) {
584 if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs, i))) { 579 if (counter_config[i].enabled && msrs->controls[i].addr) {
585 reset_value[i] = counter_config[i].count; 580 reset_value[i] = counter_config[i].count;
586 pmc_setup_one_p4_counter(i); 581 pmc_setup_one_p4_counter(i);
587 CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); 582 wrmsrl(p4_counters[VIRT_CTR(stag, i)].counter_address,
583 -(u64)counter_config[i].count);
588 } else { 584 } else {
589 reset_value[i] = 0; 585 reset_value[i] = 0;
590 } 586 }
@@ -624,14 +620,16 @@ static int p4_check_ctrs(struct pt_regs * const regs,
624 620
625 real = VIRT_CTR(stag, i); 621 real = VIRT_CTR(stag, i);
626 622
627 CCCR_READ(low, high, real); 623 rdmsr(p4_counters[real].cccr_address, low, high);
628 CTR_READ(ctr, high, real); 624 rdmsr(p4_counters[real].counter_address, ctr, high);
629 if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) { 625 if (CCCR_OVF_P(low) || !(ctr & OP_CTR_OVERFLOW)) {
630 oprofile_add_sample(regs, i); 626 oprofile_add_sample(regs, i);
631 CTR_WRITE(reset_value[i], real); 627 wrmsrl(p4_counters[real].counter_address,
628 -(u64)reset_value[i]);
632 CCCR_CLEAR_OVF(low); 629 CCCR_CLEAR_OVF(low);
633 CCCR_WRITE(low, high, real); 630 wrmsr(p4_counters[real].cccr_address, low, high);
634 CTR_WRITE(reset_value[i], real); 631 wrmsrl(p4_counters[real].counter_address,
632 -(u64)reset_value[i]);
635 } 633 }
636 } 634 }
637 635
@@ -653,9 +651,9 @@ static void p4_start(struct op_msrs const * const msrs)
653 for (i = 0; i < num_counters; ++i) { 651 for (i = 0; i < num_counters; ++i) {
654 if (!reset_value[i]) 652 if (!reset_value[i])
655 continue; 653 continue;
656 CCCR_READ(low, high, VIRT_CTR(stag, i)); 654 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
657 CCCR_SET_ENABLE(low); 655 CCCR_SET_ENABLE(low);
658 CCCR_WRITE(low, high, VIRT_CTR(stag, i)); 656 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
659 } 657 }
660} 658}
661 659
@@ -670,9 +668,9 @@ static void p4_stop(struct op_msrs const * const msrs)
670 for (i = 0; i < num_counters; ++i) { 668 for (i = 0; i < num_counters; ++i) {
671 if (!reset_value[i]) 669 if (!reset_value[i])
672 continue; 670 continue;
673 CCCR_READ(low, high, VIRT_CTR(stag, i)); 671 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
674 CCCR_SET_DISABLE(low); 672 CCCR_SET_DISABLE(low);
675 CCCR_WRITE(low, high, VIRT_CTR(stag, i)); 673 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
676 } 674 }
677} 675}
678 676
@@ -680,8 +678,8 @@ static void p4_shutdown(struct op_msrs const * const msrs)
680{ 678{
681 int i; 679 int i;
682 680
683 for (i = 0 ; i < num_counters ; ++i) { 681 for (i = 0; i < num_counters; ++i) {
684 if (CTR_IS_RESERVED(msrs, i)) 682 if (msrs->counters[i].addr)
685 release_perfctr_nmi(msrs->counters[i].addr); 683 release_perfctr_nmi(msrs->counters[i].addr);
686 } 684 }
687 /* 685 /*
@@ -689,15 +687,15 @@ static void p4_shutdown(struct op_msrs const * const msrs)
689 * conjunction with the counter registers (hence the starting offset). 687 * conjunction with the counter registers (hence the starting offset).
690 * This saves a few bits. 688 * This saves a few bits.
691 */ 689 */
692 for (i = num_counters ; i < num_controls ; ++i) { 690 for (i = num_counters; i < num_controls; ++i) {
693 if (CTRL_IS_RESERVED(msrs, i)) 691 if (msrs->controls[i].addr)
694 release_evntsel_nmi(msrs->controls[i].addr); 692 release_evntsel_nmi(msrs->controls[i].addr);
695 } 693 }
696} 694}
697 695
698 696
699#ifdef CONFIG_SMP 697#ifdef CONFIG_SMP
700struct op_x86_model_spec const op_p4_ht2_spec = { 698struct op_x86_model_spec op_p4_ht2_spec = {
701 .num_counters = NUM_COUNTERS_HT2, 699 .num_counters = NUM_COUNTERS_HT2,
702 .num_controls = NUM_CONTROLS_HT2, 700 .num_controls = NUM_CONTROLS_HT2,
703 .fill_in_addresses = &p4_fill_in_addresses, 701 .fill_in_addresses = &p4_fill_in_addresses,
@@ -709,7 +707,7 @@ struct op_x86_model_spec const op_p4_ht2_spec = {
709}; 707};
710#endif 708#endif
711 709
712struct op_x86_model_spec const op_p4_spec = { 710struct op_x86_model_spec op_p4_spec = {
713 .num_counters = NUM_COUNTERS_NON_HT, 711 .num_counters = NUM_COUNTERS_NON_HT,
714 .num_controls = NUM_CONTROLS_NON_HT, 712 .num_controls = NUM_CONTROLS_NON_HT,
715 .fill_in_addresses = &p4_fill_in_addresses, 713 .fill_in_addresses = &p4_fill_in_addresses,
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
index 4da7230b3d17..4899215999de 100644
--- a/arch/x86/oprofile/op_model_ppro.c
+++ b/arch/x86/oprofile/op_model_ppro.c
@@ -10,6 +10,7 @@
10 * @author Philippe Elie 10 * @author Philippe Elie
11 * @author Graydon Hoare 11 * @author Graydon Hoare
12 * @author Andi Kleen 12 * @author Andi Kleen
13 * @author Robert Richter <robert.richter@amd.com>
13 */ 14 */
14 15
15#include <linux/oprofile.h> 16#include <linux/oprofile.h>
@@ -18,7 +19,6 @@
18#include <asm/msr.h> 19#include <asm/msr.h>
19#include <asm/apic.h> 20#include <asm/apic.h>
20#include <asm/nmi.h> 21#include <asm/nmi.h>
21#include <asm/perf_counter.h>
22 22
23#include "op_x86_model.h" 23#include "op_x86_model.h"
24#include "op_counter.h" 24#include "op_counter.h"
@@ -26,20 +26,7 @@
26static int num_counters = 2; 26static int num_counters = 2;
27static int counter_width = 32; 27static int counter_width = 32;
28 28
29#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) 29#define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21))
30#define CTR_OVERFLOWED(n) (!((n) & (1ULL<<(counter_width-1))))
31
32#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
33#define CTRL_READ(l, h, msrs, c) do {rdmsr((msrs->controls[(c)].addr), (l), (h)); } while (0)
34#define CTRL_WRITE(l, h, msrs, c) do {wrmsr((msrs->controls[(c)].addr), (l), (h)); } while (0)
35#define CTRL_SET_ACTIVE(n) (n |= (1<<22))
36#define CTRL_SET_INACTIVE(n) (n &= ~(1<<22))
37#define CTRL_CLEAR(x) (x &= (1<<21))
38#define CTRL_SET_ENABLE(val) (val |= 1<<20)
39#define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16))
40#define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17))
41#define CTRL_SET_UM(val, m) (val |= (m << 8))
42#define CTRL_SET_EVENT(val, e) (val |= e)
43 30
44static u64 *reset_value; 31static u64 *reset_value;
45 32
@@ -63,9 +50,10 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs)
63} 50}
64 51
65 52
66static void ppro_setup_ctrs(struct op_msrs const * const msrs) 53static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
54 struct op_msrs const * const msrs)
67{ 55{
68 unsigned int low, high; 56 u64 val;
69 int i; 57 int i;
70 58
71 if (!reset_value) { 59 if (!reset_value) {
@@ -93,36 +81,30 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
93 } 81 }
94 82
95 /* clear all counters */ 83 /* clear all counters */
96 for (i = 0 ; i < num_counters; ++i) { 84 for (i = 0; i < num_counters; ++i) {
97 if (unlikely(!CTRL_IS_RESERVED(msrs, i))) 85 if (unlikely(!msrs->controls[i].addr))
98 continue; 86 continue;
99 CTRL_READ(low, high, msrs, i); 87 rdmsrl(msrs->controls[i].addr, val);
100 CTRL_CLEAR(low); 88 val &= model->reserved;
101 CTRL_WRITE(low, high, msrs, i); 89 wrmsrl(msrs->controls[i].addr, val);
102 } 90 }
103 91
104 /* avoid a false detection of ctr overflows in NMI handler */ 92 /* avoid a false detection of ctr overflows in NMI handler */
105 for (i = 0; i < num_counters; ++i) { 93 for (i = 0; i < num_counters; ++i) {
106 if (unlikely(!CTR_IS_RESERVED(msrs, i))) 94 if (unlikely(!msrs->counters[i].addr))
107 continue; 95 continue;
108 wrmsrl(msrs->counters[i].addr, -1LL); 96 wrmsrl(msrs->counters[i].addr, -1LL);
109 } 97 }
110 98
111 /* enable active counters */ 99 /* enable active counters */
112 for (i = 0; i < num_counters; ++i) { 100 for (i = 0; i < num_counters; ++i) {
113 if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { 101 if (counter_config[i].enabled && msrs->counters[i].addr) {
114 reset_value[i] = counter_config[i].count; 102 reset_value[i] = counter_config[i].count;
115
116 wrmsrl(msrs->counters[i].addr, -reset_value[i]); 103 wrmsrl(msrs->counters[i].addr, -reset_value[i]);
117 104 rdmsrl(msrs->controls[i].addr, val);
118 CTRL_READ(low, high, msrs, i); 105 val &= model->reserved;
119 CTRL_CLEAR(low); 106 val |= op_x86_get_ctrl(model, &counter_config[i]);
120 CTRL_SET_ENABLE(low); 107 wrmsrl(msrs->controls[i].addr, val);
121 CTRL_SET_USR(low, counter_config[i].user);
122 CTRL_SET_KERN(low, counter_config[i].kernel);
123 CTRL_SET_UM(low, counter_config[i].unit_mask);
124 CTRL_SET_EVENT(low, counter_config[i].event);
125 CTRL_WRITE(low, high, msrs, i);
126 } else { 108 } else {
127 reset_value[i] = 0; 109 reset_value[i] = 0;
128 } 110 }
@@ -143,14 +125,14 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
143 if (unlikely(!reset_value)) 125 if (unlikely(!reset_value))
144 goto out; 126 goto out;
145 127
146 for (i = 0 ; i < num_counters; ++i) { 128 for (i = 0; i < num_counters; ++i) {
147 if (!reset_value[i]) 129 if (!reset_value[i])
148 continue; 130 continue;
149 rdmsrl(msrs->counters[i].addr, val); 131 rdmsrl(msrs->counters[i].addr, val);
150 if (CTR_OVERFLOWED(val)) { 132 if (val & (1ULL << (counter_width - 1)))
151 oprofile_add_sample(regs, i); 133 continue;
152 wrmsrl(msrs->counters[i].addr, -reset_value[i]); 134 oprofile_add_sample(regs, i);
153 } 135 wrmsrl(msrs->counters[i].addr, -reset_value[i]);
154 } 136 }
155 137
156out: 138out:
@@ -171,16 +153,16 @@ out:
171 153
172static void ppro_start(struct op_msrs const * const msrs) 154static void ppro_start(struct op_msrs const * const msrs)
173{ 155{
174 unsigned int low, high; 156 u64 val;
175 int i; 157 int i;
176 158
177 if (!reset_value) 159 if (!reset_value)
178 return; 160 return;
179 for (i = 0; i < num_counters; ++i) { 161 for (i = 0; i < num_counters; ++i) {
180 if (reset_value[i]) { 162 if (reset_value[i]) {
181 CTRL_READ(low, high, msrs, i); 163 rdmsrl(msrs->controls[i].addr, val);
182 CTRL_SET_ACTIVE(low); 164 val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
183 CTRL_WRITE(low, high, msrs, i); 165 wrmsrl(msrs->controls[i].addr, val);
184 } 166 }
185 } 167 }
186} 168}
@@ -188,7 +170,7 @@ static void ppro_start(struct op_msrs const * const msrs)
188 170
189static void ppro_stop(struct op_msrs const * const msrs) 171static void ppro_stop(struct op_msrs const * const msrs)
190{ 172{
191 unsigned int low, high; 173 u64 val;
192 int i; 174 int i;
193 175
194 if (!reset_value) 176 if (!reset_value)
@@ -196,9 +178,9 @@ static void ppro_stop(struct op_msrs const * const msrs)
196 for (i = 0; i < num_counters; ++i) { 178 for (i = 0; i < num_counters; ++i) {
197 if (!reset_value[i]) 179 if (!reset_value[i])
198 continue; 180 continue;
199 CTRL_READ(low, high, msrs, i); 181 rdmsrl(msrs->controls[i].addr, val);
200 CTRL_SET_INACTIVE(low); 182 val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
201 CTRL_WRITE(low, high, msrs, i); 183 wrmsrl(msrs->controls[i].addr, val);
202 } 184 }
203} 185}
204 186
@@ -206,12 +188,12 @@ static void ppro_shutdown(struct op_msrs const * const msrs)
206{ 188{
207 int i; 189 int i;
208 190
209 for (i = 0 ; i < num_counters ; ++i) { 191 for (i = 0; i < num_counters; ++i) {
210 if (CTR_IS_RESERVED(msrs, i)) 192 if (msrs->counters[i].addr)
211 release_perfctr_nmi(MSR_P6_PERFCTR0 + i); 193 release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
212 } 194 }
213 for (i = 0 ; i < num_counters ; ++i) { 195 for (i = 0; i < num_counters; ++i) {
214 if (CTRL_IS_RESERVED(msrs, i)) 196 if (msrs->controls[i].addr)
215 release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); 197 release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
216 } 198 }
217 if (reset_value) { 199 if (reset_value) {
@@ -222,8 +204,9 @@ static void ppro_shutdown(struct op_msrs const * const msrs)
222 204
223 205
224struct op_x86_model_spec op_ppro_spec = { 206struct op_x86_model_spec op_ppro_spec = {
225 .num_counters = 2, /* can be overriden */ 207 .num_counters = 2,
226 .num_controls = 2, /* dito */ 208 .num_controls = 2,
209 .reserved = MSR_PPRO_EVENTSEL_RESERVED,
227 .fill_in_addresses = &ppro_fill_in_addresses, 210 .fill_in_addresses = &ppro_fill_in_addresses,
228 .setup_ctrs = &ppro_setup_ctrs, 211 .setup_ctrs = &ppro_setup_ctrs,
229 .check_ctrs = &ppro_check_ctrs, 212 .check_ctrs = &ppro_check_ctrs,
@@ -241,7 +224,7 @@ struct op_x86_model_spec op_ppro_spec = {
241 * the specific CPU. 224 * the specific CPU.
242 */ 225 */
243 226
244void arch_perfmon_setup_counters(void) 227static void arch_perfmon_setup_counters(void)
245{ 228{
246 union cpuid10_eax eax; 229 union cpuid10_eax eax;
247 230
@@ -259,11 +242,17 @@ void arch_perfmon_setup_counters(void)
259 242
260 op_arch_perfmon_spec.num_counters = num_counters; 243 op_arch_perfmon_spec.num_counters = num_counters;
261 op_arch_perfmon_spec.num_controls = num_counters; 244 op_arch_perfmon_spec.num_controls = num_counters;
262 op_ppro_spec.num_counters = num_counters; 245}
263 op_ppro_spec.num_controls = num_counters; 246
247static int arch_perfmon_init(struct oprofile_operations *ignore)
248{
249 arch_perfmon_setup_counters();
250 return 0;
264} 251}
265 252
266struct op_x86_model_spec op_arch_perfmon_spec = { 253struct op_x86_model_spec op_arch_perfmon_spec = {
254 .reserved = MSR_PPRO_EVENTSEL_RESERVED,
255 .init = &arch_perfmon_init,
267 /* num_counters/num_controls filled in at runtime */ 256 /* num_counters/num_controls filled in at runtime */
268 .fill_in_addresses = &ppro_fill_in_addresses, 257 .fill_in_addresses = &ppro_fill_in_addresses,
269 /* user space does the cpuid check for available events */ 258 /* user space does the cpuid check for available events */
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index 825e79064d64..b83776180c7f 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
@@ -6,51 +6,66 @@
6 * @remark Read the file COPYING 6 * @remark Read the file COPYING
7 * 7 *
8 * @author Graydon Hoare 8 * @author Graydon Hoare
9 * @author Robert Richter <robert.richter@amd.com>
9 */ 10 */
10 11
11#ifndef OP_X86_MODEL_H 12#ifndef OP_X86_MODEL_H
12#define OP_X86_MODEL_H 13#define OP_X86_MODEL_H
13 14
14struct op_saved_msr { 15#include <asm/types.h>
15 unsigned int high; 16#include <asm/perf_counter.h>
16 unsigned int low;
17};
18 17
19struct op_msr { 18struct op_msr {
20 unsigned long addr; 19 unsigned long addr;
21 struct op_saved_msr saved; 20 u64 saved;
22}; 21};
23 22
24struct op_msrs { 23struct op_msrs {
25 struct op_msr *counters; 24 struct op_msr *counters;
26 struct op_msr *controls; 25 struct op_msr *controls;
26 struct op_msr *multiplex;
27}; 27};
28 28
29struct pt_regs; 29struct pt_regs;
30 30
31struct oprofile_operations;
32
31/* The model vtable abstracts the differences between 33/* The model vtable abstracts the differences between
32 * various x86 CPU models' perfctr support. 34 * various x86 CPU models' perfctr support.
33 */ 35 */
34struct op_x86_model_spec { 36struct op_x86_model_spec {
35 int (*init)(struct oprofile_operations *ops); 37 unsigned int num_counters;
36 void (*exit)(void); 38 unsigned int num_controls;
37 unsigned int num_counters; 39 unsigned int num_virt_counters;
38 unsigned int num_controls; 40 u64 reserved;
39 void (*fill_in_addresses)(struct op_msrs * const msrs); 41 u16 event_mask;
40 void (*setup_ctrs)(struct op_msrs const * const msrs); 42 int (*init)(struct oprofile_operations *ops);
41 int (*check_ctrs)(struct pt_regs * const regs, 43 void (*exit)(void);
42 struct op_msrs const * const msrs); 44 void (*fill_in_addresses)(struct op_msrs * const msrs);
43 void (*start)(struct op_msrs const * const msrs); 45 void (*setup_ctrs)(struct op_x86_model_spec const *model,
44 void (*stop)(struct op_msrs const * const msrs); 46 struct op_msrs const * const msrs);
45 void (*shutdown)(struct op_msrs const * const msrs); 47 int (*check_ctrs)(struct pt_regs * const regs,
48 struct op_msrs const * const msrs);
49 void (*start)(struct op_msrs const * const msrs);
50 void (*stop)(struct op_msrs const * const msrs);
51 void (*shutdown)(struct op_msrs const * const msrs);
52#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
53 void (*switch_ctrl)(struct op_x86_model_spec const *model,
54 struct op_msrs const * const msrs);
55#endif
46}; 56};
47 57
58struct op_counter_config;
59
60extern u64 op_x86_get_ctrl(struct op_x86_model_spec const *model,
61 struct op_counter_config *counter_config);
62extern int op_x86_phys_to_virt(int phys);
63extern int op_x86_virt_to_phys(int virt);
64
48extern struct op_x86_model_spec op_ppro_spec; 65extern struct op_x86_model_spec op_ppro_spec;
49extern struct op_x86_model_spec const op_p4_spec; 66extern struct op_x86_model_spec op_p4_spec;
50extern struct op_x86_model_spec const op_p4_ht2_spec; 67extern struct op_x86_model_spec op_p4_ht2_spec;
51extern struct op_x86_model_spec const op_amd_spec; 68extern struct op_x86_model_spec op_amd_spec;
52extern struct op_x86_model_spec op_arch_perfmon_spec; 69extern struct op_x86_model_spec op_arch_perfmon_spec;
53 70
54extern void arch_perfmon_setup_counters(void);
55
56#endif /* OP_X86_MODEL_H */ 71#endif /* OP_X86_MODEL_H */
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
index bd13c3e4c6db..347d882b3bb3 100644
--- a/arch/x86/pci/direct.c
+++ b/arch/x86/pci/direct.c
@@ -192,13 +192,14 @@ struct pci_raw_ops pci_direct_conf2 = {
192static int __init pci_sanity_check(struct pci_raw_ops *o) 192static int __init pci_sanity_check(struct pci_raw_ops *o)
193{ 193{
194 u32 x = 0; 194 u32 x = 0;
195 int devfn; 195 int year, devfn;
196 196
197 if (pci_probe & PCI_NO_CHECKS) 197 if (pci_probe & PCI_NO_CHECKS)
198 return 1; 198 return 1;
199 /* Assume Type 1 works for newer systems. 199 /* Assume Type 1 works for newer systems.
200 This handles machines that don't have anything on PCI Bus 0. */ 200 This handles machines that don't have anything on PCI Bus 0. */
201 if (dmi_get_year(DMI_BIOS_DATE) >= 2001) 201 dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL);
202 if (year >= 2001)
202 return 1; 203 return 1;
203 204
204 for (devfn = 0; devfn < 0x100; devfn++) { 205 for (devfn = 0; devfn < 0x100; devfn++) {
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
index 7410640db173..3bb4fc21f4f2 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
@@ -8,6 +8,7 @@ endif
8# Make sure early boot has no stackprotector 8# Make sure early boot has no stackprotector
9nostackp := $(call cc-option, -fno-stack-protector) 9nostackp := $(call cc-option, -fno-stack-protector)
10CFLAGS_enlighten.o := $(nostackp) 10CFLAGS_enlighten.o := $(nostackp)
11CFLAGS_mmu.o := $(nostackp)
11 12
12obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ 13obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
13 time.o xen-asm.o xen-asm_$(BITS).o \ 14 time.o xen-asm.o xen-asm_$(BITS).o \
@@ -16,3 +17,4 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
16obj-$(CONFIG_SMP) += smp.o 17obj-$(CONFIG_SMP) += smp.o
17obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o 18obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
18obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o 19obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o
20
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index eb33aaa8415d..0dd0c2c6cae0 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -51,6 +51,7 @@
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#include <asm/tlbflush.h> 52#include <asm/tlbflush.h>
53#include <asm/reboot.h> 53#include <asm/reboot.h>
54#include <asm/stackprotector.h>
54 55
55#include "xen-ops.h" 56#include "xen-ops.h"
56#include "mmu.h" 57#include "mmu.h"
@@ -330,18 +331,28 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
330 unsigned long frames[pages]; 331 unsigned long frames[pages];
331 int f; 332 int f;
332 333
333 /* A GDT can be up to 64k in size, which corresponds to 8192 334 /*
334 8-byte entries, or 16 4k pages.. */ 335 * A GDT can be up to 64k in size, which corresponds to 8192
336 * 8-byte entries, or 16 4k pages..
337 */
335 338
336 BUG_ON(size > 65536); 339 BUG_ON(size > 65536);
337 BUG_ON(va & ~PAGE_MASK); 340 BUG_ON(va & ~PAGE_MASK);
338 341
339 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { 342 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
340 int level; 343 int level;
341 pte_t *ptep = lookup_address(va, &level); 344 pte_t *ptep;
342 unsigned long pfn, mfn; 345 unsigned long pfn, mfn;
343 void *virt; 346 void *virt;
344 347
348 /*
349 * The GDT is per-cpu and is in the percpu data area.
350 * That can be virtually mapped, so we need to do a
351 * page-walk to get the underlying MFN for the
352 * hypercall. The page can also be in the kernel's
353 * linear range, so we need to RO that mapping too.
354 */
355 ptep = lookup_address(va, &level);
345 BUG_ON(ptep == NULL); 356 BUG_ON(ptep == NULL);
346 357
347 pfn = pte_pfn(*ptep); 358 pfn = pte_pfn(*ptep);
@@ -358,6 +369,44 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
358 BUG(); 369 BUG();
359} 370}
360 371
372/*
373 * load_gdt for early boot, when the gdt is only mapped once
374 */
375static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
376{
377 unsigned long va = dtr->address;
378 unsigned int size = dtr->size + 1;
379 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
380 unsigned long frames[pages];
381 int f;
382
383 /*
384 * A GDT can be up to 64k in size, which corresponds to 8192
385 * 8-byte entries, or 16 4k pages..
386 */
387
388 BUG_ON(size > 65536);
389 BUG_ON(va & ~PAGE_MASK);
390
391 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
392 pte_t pte;
393 unsigned long pfn, mfn;
394
395 pfn = virt_to_pfn(va);
396 mfn = pfn_to_mfn(pfn);
397
398 pte = pfn_pte(pfn, PAGE_KERNEL_RO);
399
400 if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
401 BUG();
402
403 frames[f] = mfn;
404 }
405
406 if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
407 BUG();
408}
409
361static void load_TLS_descriptor(struct thread_struct *t, 410static void load_TLS_descriptor(struct thread_struct *t,
362 unsigned int cpu, unsigned int i) 411 unsigned int cpu, unsigned int i)
363{ 412{
@@ -581,6 +630,29 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
581 preempt_enable(); 630 preempt_enable();
582} 631}
583 632
633/*
634 * Version of write_gdt_entry for use at early boot-time needed to
635 * update an entry as simply as possible.
636 */
637static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry,
638 const void *desc, int type)
639{
640 switch (type) {
641 case DESC_LDT:
642 case DESC_TSS:
643 /* ignore */
644 break;
645
646 default: {
647 xmaddr_t maddr = virt_to_machine(&dt[entry]);
648
649 if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc))
650 dt[entry] = *(struct desc_struct *)desc;
651 }
652
653 }
654}
655
584static void xen_load_sp0(struct tss_struct *tss, 656static void xen_load_sp0(struct tss_struct *tss,
585 struct thread_struct *thread) 657 struct thread_struct *thread)
586{ 658{
@@ -714,7 +786,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
714 set: 786 set:
715 base = ((u64)high << 32) | low; 787 base = ((u64)high << 32) | low;
716 if (HYPERVISOR_set_segment_base(which, base) != 0) 788 if (HYPERVISOR_set_segment_base(which, base) != 0)
717 ret = -EFAULT; 789 ret = -EIO;
718 break; 790 break;
719#endif 791#endif
720 792
@@ -965,6 +1037,23 @@ static const struct machine_ops __initdata xen_machine_ops = {
965 .emergency_restart = xen_emergency_restart, 1037 .emergency_restart = xen_emergency_restart,
966}; 1038};
967 1039
1040/*
1041 * Set up the GDT and segment registers for -fstack-protector. Until
1042 * we do this, we have to be careful not to call any stack-protected
1043 * function, which is most of the kernel.
1044 */
1045static void __init xen_setup_stackprotector(void)
1046{
1047 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot;
1048 pv_cpu_ops.load_gdt = xen_load_gdt_boot;
1049
1050 setup_stack_canary_segment(0);
1051 switch_to_new_gdt(0);
1052
1053 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry;
1054 pv_cpu_ops.load_gdt = xen_load_gdt;
1055}
1056
968/* First C function to be called on Xen boot */ 1057/* First C function to be called on Xen boot */
969asmlinkage void __init xen_start_kernel(void) 1058asmlinkage void __init xen_start_kernel(void)
970{ 1059{
@@ -983,13 +1072,28 @@ asmlinkage void __init xen_start_kernel(void)
983 pv_apic_ops = xen_apic_ops; 1072 pv_apic_ops = xen_apic_ops;
984 pv_mmu_ops = xen_mmu_ops; 1073 pv_mmu_ops = xen_mmu_ops;
985 1074
986#ifdef CONFIG_X86_64
987 /* 1075 /*
988 * Setup percpu state. We only need to do this for 64-bit 1076 * Set up some pagetable state before starting to set any ptes.
989 * because 32-bit already has %fs set properly.
990 */ 1077 */
991 load_percpu_segment(0); 1078
992#endif 1079 /* Prevent unwanted bits from being set in PTEs. */
1080 __supported_pte_mask &= ~_PAGE_GLOBAL;
1081 if (!xen_initial_domain())
1082 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
1083
1084 __supported_pte_mask |= _PAGE_IOMAP;
1085
1086 xen_setup_features();
1087
1088 /* Get mfn list */
1089 if (!xen_feature(XENFEAT_auto_translated_physmap))
1090 xen_build_dynamic_phys_to_machine();
1091
1092 /*
1093 * Set up kernel GDT and segment registers, mainly so that
1094 * -fstack-protector code can be executed.
1095 */
1096 xen_setup_stackprotector();
993 1097
994 xen_init_irq_ops(); 1098 xen_init_irq_ops();
995 xen_init_cpuid_mask(); 1099 xen_init_cpuid_mask();
@@ -1001,8 +1105,6 @@ asmlinkage void __init xen_start_kernel(void)
1001 set_xen_basic_apic_ops(); 1105 set_xen_basic_apic_ops();
1002#endif 1106#endif
1003 1107
1004 xen_setup_features();
1005
1006 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { 1108 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
1007 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start; 1109 pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
1008 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit; 1110 pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
@@ -1019,17 +1121,8 @@ asmlinkage void __init xen_start_kernel(void)
1019 1121
1020 xen_smp_init(); 1122 xen_smp_init();
1021 1123
1022 /* Get mfn list */
1023 if (!xen_feature(XENFEAT_auto_translated_physmap))
1024 xen_build_dynamic_phys_to_machine();
1025
1026 pgd = (pgd_t *)xen_start_info->pt_base; 1124 pgd = (pgd_t *)xen_start_info->pt_base;
1027 1125
1028 /* Prevent unwanted bits from being set in PTEs. */
1029 __supported_pte_mask &= ~_PAGE_GLOBAL;
1030 if (!xen_initial_domain())
1031 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
1032
1033#ifdef CONFIG_X86_64 1126#ifdef CONFIG_X86_64
1034 /* Work out if we support NX */ 1127 /* Work out if we support NX */
1035 check_efer(); 1128 check_efer();
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 429834ec1687..fe03eeed7b48 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -236,6 +236,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
236 ctxt->user_regs.ss = __KERNEL_DS; 236 ctxt->user_regs.ss = __KERNEL_DS;
237#ifdef CONFIG_X86_32 237#ifdef CONFIG_X86_32
238 ctxt->user_regs.fs = __KERNEL_PERCPU; 238 ctxt->user_regs.fs = __KERNEL_PERCPU;
239 ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
239#else 240#else
240 ctxt->gs_base_kernel = per_cpu_offset(cpu); 241 ctxt->gs_base_kernel = per_cpu_offset(cpu);
241#endif 242#endif
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 5601506f2dd9..36a5141108df 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -187,7 +187,6 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
187 struct xen_spinlock *prev; 187 struct xen_spinlock *prev;
188 int irq = __get_cpu_var(lock_kicker_irq); 188 int irq = __get_cpu_var(lock_kicker_irq);
189 int ret; 189 int ret;
190 unsigned long flags;
191 u64 start; 190 u64 start;
192 191
193 /* If kicker interrupts not initialized yet, just spin */ 192 /* If kicker interrupts not initialized yet, just spin */
@@ -199,16 +198,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
199 /* announce we're spinning */ 198 /* announce we're spinning */
200 prev = spinning_lock(xl); 199 prev = spinning_lock(xl);
201 200
202 flags = __raw_local_save_flags();
203 if (irq_enable) {
204 ADD_STATS(taken_slow_irqenable, 1);
205 raw_local_irq_enable();
206 }
207
208 ADD_STATS(taken_slow, 1); 201 ADD_STATS(taken_slow, 1);
209 ADD_STATS(taken_slow_nested, prev != NULL); 202 ADD_STATS(taken_slow_nested, prev != NULL);
210 203
211 do { 204 do {
205 unsigned long flags;
206
212 /* clear pending */ 207 /* clear pending */
213 xen_clear_irq_pending(irq); 208 xen_clear_irq_pending(irq);
214 209
@@ -228,6 +223,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
228 goto out; 223 goto out;
229 } 224 }
230 225
226 flags = __raw_local_save_flags();
227 if (irq_enable) {
228 ADD_STATS(taken_slow_irqenable, 1);
229 raw_local_irq_enable();
230 }
231
231 /* 232 /*
232 * Block until irq becomes pending. If we're 233 * Block until irq becomes pending. If we're
233 * interrupted at this point (after the trylock but 234 * interrupted at this point (after the trylock but
@@ -238,13 +239,15 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
238 * pending. 239 * pending.
239 */ 240 */
240 xen_poll_irq(irq); 241 xen_poll_irq(irq);
242
243 raw_local_irq_restore(flags);
244
241 ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq)); 245 ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq));
242 } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */ 246 } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */
243 247
244 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); 248 kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
245 249
246out: 250out:
247 raw_local_irq_restore(flags);
248 unspinning_lock(xl, prev); 251 unspinning_lock(xl, prev);
249 spin_time_accum_blocked(start); 252 spin_time_accum_blocked(start);
250 253
@@ -323,8 +326,13 @@ static void xen_spin_unlock(struct raw_spinlock *lock)
323 smp_wmb(); /* make sure no writes get moved after unlock */ 326 smp_wmb(); /* make sure no writes get moved after unlock */
324 xl->lock = 0; /* release lock */ 327 xl->lock = 0; /* release lock */
325 328
326 /* make sure unlock happens before kick */ 329 /*
327 barrier(); 330 * Make sure unlock happens before checking for waiting
331 * spinners. We need a strong barrier to enforce the
332 * write-read ordering to different memory locations, as the
333 * CPU makes no implied guarantees about their ordering.
334 */
335 mb();
328 336
329 if (unlikely(xl->spinners)) 337 if (unlikely(xl->spinners))
330 xen_spin_unlock_slow(xl); 338 xen_spin_unlock_slow(xl);
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index dd1a7a4a1cea..beb3a6bdb61d 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -68,4 +68,7 @@
68#define SO_TIMESTAMPING 37 68#define SO_TIMESTAMPING 37
69#define SCM_TIMESTAMPING SO_TIMESTAMPING 69#define SCM_TIMESTAMPING SO_TIMESTAMPING
70 70
71#define SO_PROTOCOL 38
72#define SO_DOMAIN 39
73
71#endif /* _XTENSA_SOCKET_H */ 74#endif /* _XTENSA_SOCKET_H */
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index edad4156d89a..2f0b86b37cf9 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -545,7 +545,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
545 spin_unlock_irqrestore(&lp->lock, flags); 545 spin_unlock_irqrestore(&lp->lock, flags);
546 546
547 dev_kfree_skb(skb); 547 dev_kfree_skb(skb);
548 return 0; 548 return NETDEV_TX_OK;
549} 549}
550 550
551 551